ShineBridge v1.12.0 — Feature: Prognosebasierter Zwangslade-Timeout (Open-Meteo)
Neuer Standort-Bereich im Einstellungen-Tab (Breitengrad/Längengrad, optional, site-weit statt pro Gerät). Neues Modul weather_forecast.py fragt Open-Meteos kostenlose stündliche Solarstrahlungs-Prognose (shortwave_radiation, 48h voraus, timezone=auto) ab, gecacht alle 3h. adjusted_timeout_h() passt den Zwangslade-Timeout adaptiv an: - bald nennenswerte Sonne zu erwarten (naechste 3h) -> Timeout verlaengern (x1.75, gedeckelt auf Basiswert+4h) - auch im 12h-Fenster keine nennenswerte Sonne zu erwarten -> Timeout verkuerzen (x0.5, min. 0.5h) statt sinnlos den vollen Timeout abzuwarten - ohne Standort (lat/lon leer): unveraendertes Verhalten, Feature ist Opt-in EmsController.update() bekommt einen neuen optionalen timeout_override_h- Parameter statt selbst Standortdaten zu kennen — Wetter-Logik bleibt im Poll-Loop, EmsController fokussiert auf die eigentliche Lade-Steuerung. Auf Sonnenstand-Berechnung bewusst verzichtet — die stuendliche Strahlungs- prognose bildet Tag/Nacht-Verlauf implizit schon ab, eigene Ephemeriden- Berechnung waere doppelte Arbeit ohne Mehrwert. Teil 2 von 2 des 'Prognosebasiertes Laden'-Roadmap-Punkts, damit komplett. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -233,6 +233,18 @@
|
||||
<button class="btn btn-primary" onclick="saveMqtt()">Speichern & Neu starten</button>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h3>Standort</h3>
|
||||
<p style="color:var(--text-dim);font-size:.85rem;margin:0 0 .75rem">Für die prognosebasierte Anpassung des Zwangslade-Timeouts (Solarstrahlungs-Vorhersage via Open-Meteo). Optional — leer lassen deaktiviert die Anpassung, Zwangsladen nutzt dann weiter den festen Timeout.</p>
|
||||
<div style="display:flex;gap:10px;flex-wrap:wrap">
|
||||
<div class="field" style="max-width:180px"><label>Breitengrad</label>
|
||||
<input type="number" id="cfg-site-lat" step="0.0001" placeholder="z.B. 52.5200"></div>
|
||||
<div class="field" style="max-width:180px"><label>Längengrad</label>
|
||||
<input type="number" id="cfg-site-lon" step="0.0001" placeholder="z.B. 13.4050"></div>
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="saveLocation()">Speichern</button>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h3>Stromtarif</h3>
|
||||
<div class="field">
|
||||
@@ -1238,6 +1250,20 @@ async function loadSettings() {
|
||||
document.getElementById("cfg-monthly-rate").value = cfg.monthly_rate_eur ?? 0;
|
||||
document.getElementById("cfg-grundpreis").value = cfg.grundpreis_eur_per_month ?? 0;
|
||||
document.getElementById("cfg-backup-retention").value = cfg.config_backup_retention_days ?? 14;
|
||||
document.getElementById("cfg-site-lat").value = cfg.site_lat ?? "";
|
||||
document.getElementById("cfg-site-lon").value = cfg.site_lon ?? "";
|
||||
}
|
||||
|
||||
async function saveLocation() {
|
||||
const lat = document.getElementById("cfg-site-lat").value;
|
||||
const lon = document.getElementById("cfg-site-lon").value;
|
||||
try {
|
||||
await fetchJSON(api("api/config"), {
|
||||
method: "POST", headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify({ site_lat: lat === "" ? null : lat, site_lon: lon === "" ? null : lon }),
|
||||
});
|
||||
showToast("Gespeichert!", "ok");
|
||||
} catch(e) { showToast("Fehler beim Speichern", "err"); }
|
||||
}
|
||||
|
||||
async function savePrices() {
|
||||
|
||||
Reference in New Issue
Block a user