Fix: Stromtarif-Einstellungen nach Neustart verloren + Finanzen-Layout (v1.8.22)
State.mqtt_cfg wurde beim Start nur mit 4 MQTT-Keys initialisiert — alle Tarif/Billing-Keys fehlten, wurden nach Neustart auf Defaults zurückgesetzt. Fix: alle persistenten Keys aus load_config() in State.mqtt_cfg übernehmen. Finanzen-Tab: mehr Abstände, größere Karten (22px Wert), Abschnittsüberschriften, Trennlinie vor dem Chart. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
name: ShineBridge
|
||||
version: "1.8.21"
|
||||
version: "1.8.22"
|
||||
slug: shinebridge
|
||||
description: Growatt Wechselrichter lokal in Home Assistant — Modbus TCP via ShineLAN-X, MQTT Discovery, Web UI
|
||||
url: https://gitea.bitfire.work/retr0/shinebridge
|
||||
|
||||
@@ -952,8 +952,12 @@ if __name__ == "__main__":
|
||||
history.init_db()
|
||||
cfg = load_config()
|
||||
with State.lock:
|
||||
State.mqtt_cfg = {k: cfg[k] for k in
|
||||
("mqtt_broker", "mqtt_port", "mqtt_user", "mqtt_pass")}
|
||||
State.mqtt_cfg = {k: cfg[k] for k in (
|
||||
"mqtt_broker", "mqtt_port", "mqtt_user", "mqtt_pass",
|
||||
"price_import", "price_export", "billing_day", "billing_month",
|
||||
"tariff_type", "spot_country", "spot_markup", "spot_chart",
|
||||
"billing_tracker_enabled", "monthly_rate_eur", "grundpreis_eur_per_month",
|
||||
) if k in cfg}
|
||||
State.inverters_cfg = cfg.get("inverters", [])
|
||||
State.surplus_devices_cfg = cfg.get("surplus_devices", [])
|
||||
State.z2m_base = cfg.get("z2m_base", "zigbee2mqtt")
|
||||
|
||||
@@ -957,37 +957,39 @@ async function loadFinance() {
|
||||
const lohnt = savings_eur > 0;
|
||||
const col = lohnt ? C.green : C.red;
|
||||
const icon = lohnt ? '✓' : '✗';
|
||||
empfehlung = `<div style="display:flex;align-items:center;justify-content:space-between;background:var(--surface);border:1px solid ${col};border-radius:var(--radius);padding:14px 18px;margin-bottom:16px">
|
||||
empfehlung = `<div style="display:flex;align-items:center;justify-content:space-between;background:var(--surface);border:1px solid ${col};border-radius:var(--radius);padding:18px 22px;margin-bottom:24px">
|
||||
<div>
|
||||
<div style="font-weight:700;font-size:15px;color:${col}">${icon} Flexibler Tarif würde sich ${lohnt ? 'lohnen' : 'nicht lohnen'}</div>
|
||||
<div style="font-size:12px;color:var(--text-dim);margin-top:3px">Basierend auf ${spot_days} Tagen im Abrechnungsjahr</div>
|
||||
<div style="font-size:12px;color:var(--text-dim);margin-top:5px">Basierend auf ${spot_days} Tagen im Abrechnungsjahr</div>
|
||||
</div>
|
||||
<div style="font-size:22px;font-weight:700;color:${col}">${lohnt ? '−' : '+'}${fEur(Math.abs(savings_eur))}</div>
|
||||
<div style="font-size:26px;font-weight:700;color:${col};margin-left:20px;white-space:nowrap">${lohnt ? '−' : '+'}${fEur(Math.abs(savings_eur))}</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// ── Summary-Karten ───────────────────────────────────────────
|
||||
const spotCard = spot_total_eur !== null
|
||||
? `<div class="kwh-card" style="border-top:3px solid ${C.spot}">
|
||||
<div class="kv" style="color:${C.spot}">${fEur(spot_total_eur)}</div>
|
||||
<div class="kl">Spot-Tarif (hypothetisch)<br><span style="opacity:.6">${spot_days} Tage mit Preisdaten</span></div>
|
||||
? `<div class="kwh-card" style="border-top:3px solid ${C.spot};padding:18px 10px">
|
||||
<div class="kv" style="color:${C.spot};font-size:22px">${fEur(spot_total_eur)}</div>
|
||||
<div class="kl" style="font-size:11px;margin-top:6px">Spot-Tarif (hypothetisch)<br><span style="opacity:.6">${spot_days} Tage mit Preisdaten</span></div>
|
||||
</div>`
|
||||
: `<div class="kwh-card"><div class="kv" style="color:var(--text-dim)">–</div><div class="kl">Spot-Tarif<br><span style="opacity:.6">Noch keine Daten</span></div></div>`;
|
||||
: `<div class="kwh-card" style="padding:18px 10px"><div class="kv" style="color:var(--text-dim);font-size:22px">–</div><div class="kl" style="font-size:11px;margin-top:6px">Spot-Tarif<br><span style="opacity:.6">Noch keine Daten</span></div></div>`;
|
||||
|
||||
const savCard = savings_eur !== null
|
||||
? `<div class="kwh-card" style="border-top:3px solid ${savings_eur > 0 ? C.green : C.red}">
|
||||
<div class="kv" style="color:${savings_eur > 0 ? C.green : C.red}">${savings_eur > 0 ? '−' : '+'}${fEur(Math.abs(savings_eur))}</div>
|
||||
<div class="kl">${savings_eur > 0 ? 'Ersparnis mit Spot' : 'Mehrkosten mit Spot'}<br><span style="opacity:.6">gegenüber Festpreis</span></div>
|
||||
? `<div class="kwh-card" style="border-top:3px solid ${savings_eur > 0 ? C.green : C.red};padding:18px 10px">
|
||||
<div class="kv" style="color:${savings_eur > 0 ? C.green : C.red};font-size:22px">${savings_eur > 0 ? '−' : '+'}${fEur(Math.abs(savings_eur))}</div>
|
||||
<div class="kl" style="font-size:11px;margin-top:6px">${savings_eur > 0 ? 'Ersparnis mit Spot' : 'Mehrkosten mit Spot'}<br><span style="opacity:.6">gegenüber Festpreis</span></div>
|
||||
</div>`
|
||||
: '';
|
||||
|
||||
const cards = `<div class="energy-kwh" style="margin-bottom:20px">
|
||||
<div class="kwh-card" style="border-top:3px solid ${C.fixed}">
|
||||
<div class="kv" style="color:${C.fixed}">${fEur(fixed_total_eur)}</div>
|
||||
<div class="kl">Festpreis-Kosten<br><span style="opacity:.6">${total_days} Tage</span></div>
|
||||
</div>
|
||||
${spotCard}${savCard}
|
||||
</div>`;
|
||||
const cards = `
|
||||
<div style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-dim);margin-bottom:10px">Kostenübersicht · Abrechnungsjahr</div>
|
||||
<div class="energy-kwh" style="margin-bottom:28px;gap:12px">
|
||||
<div class="kwh-card" style="border-top:3px solid ${C.fixed};padding:18px 10px">
|
||||
<div class="kv" style="color:${C.fixed};font-size:22px">${fEur(fixed_total_eur)}</div>
|
||||
<div class="kl" style="font-size:11px;margin-top:6px">Festpreis-Kosten<br><span style="opacity:.6">${total_days} Tage</span></div>
|
||||
</div>
|
||||
${spotCard}${savCard}
|
||||
</div>`;
|
||||
|
||||
// ── SVG-Balkendiagramm ────────────────────────────────────────
|
||||
const W = 600, H = 180, PL = 44, PR = 12, PT = 10, PB = 28;
|
||||
@@ -1027,13 +1029,17 @@ async function loadFinance() {
|
||||
const legend = `<text x="${PL}" y="${H+18}" font-size="10" fill="${C.fixed}">■ Festpreis</text>
|
||||
<text x="${PL+70}" y="${H+18}" font-size="10" fill="${C.spot}">■ Spot (hypothetisch)</text>`;
|
||||
|
||||
const chart = `<div style="margin-bottom:20px;overflow-x:auto">
|
||||
<svg viewBox="0 0 ${W} ${H+24}" style="width:100%;max-width:${W}px;display:block">
|
||||
${gridLines}${yLabels}${bars}${xLabels}${legend}
|
||||
</svg>
|
||||
</div>`;
|
||||
const chartSection = `
|
||||
<div style="border-top:1px solid var(--border);padding-top:24px;margin-top:4px">
|
||||
<div style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-dim);margin-bottom:14px">Kosten je Tag</div>
|
||||
<div style="overflow-x:auto">
|
||||
<svg viewBox="0 0 ${W} ${H+24}" style="width:100%;max-width:${W}px;display:block">
|
||||
${gridLines}${yLabels}${bars}${xLabels}${legend}
|
||||
</svg>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
el.innerHTML = empfehlung + cards + chart;
|
||||
el.innerHTML = `<div style="padding:4px 0">${empfehlung}${cards}${chartSection}</div>`;
|
||||
} catch(e) { el.innerHTML = '<div class="no-data">Fehler beim Laden</div>'; console.error('loadFinance:', e); }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user