v1.8.20: Fix Eigenversorgungskarte + Stromtarif-Einstellungen verloren
Bug 1 — Eigenversorgungskarte verschwindet wenn PV offline: - savings_kwh wird jetzt gesetzt wenn pv_total vorhanden (grid_exp muss nicht mehr explizit vorhanden sein, default 0.0) - Karte bleibt sichtbar auch wenn Wechselrichter offline geht Bug 2 — Stromtarif-Einstellungen gehen beim Speichern verloren: - savePrices(): parseInt mit || 1 Fallback, verhindert NaN → JSON-null - api_save_config(): None-Checks + try/except für alle numerischen Keys, save_config() wird garantiert immer aufgerufen Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
name: ShineBridge
|
name: ShineBridge
|
||||||
version: "1.8.19"
|
version: "1.8.20"
|
||||||
slug: shinebridge
|
slug: shinebridge
|
||||||
description: Growatt Wechselrichter lokal in Home Assistant — Modbus TCP via ShineLAN-X, MQTT Discovery, Web UI
|
description: Growatt Wechselrichter lokal in Home Assistant — Modbus TCP via ShineLAN-X, MQTT Discovery, Web UI
|
||||||
url: https://gitea.bitfire.work/retr0/shinebridge
|
url: https://gitea.bitfire.work/retr0/shinebridge
|
||||||
|
|||||||
+12
-9
@@ -480,22 +480,25 @@ def api_save_config():
|
|||||||
State.mqtt_cfg[k] = data[k]
|
State.mqtt_cfg[k] = data[k]
|
||||||
if data.get("mqtt_pass"):
|
if data.get("mqtt_pass"):
|
||||||
State.mqtt_cfg["mqtt_pass"] = data["mqtt_pass"]
|
State.mqtt_cfg["mqtt_pass"] = data["mqtt_pass"]
|
||||||
for k in ("price_import", "price_export", "spot_markup"):
|
for k in ("price_import", "price_export", "spot_markup", "monthly_rate_eur", "grundpreis_eur_per_month"):
|
||||||
if k in data:
|
if k in data and data[k] is not None:
|
||||||
|
try:
|
||||||
State.mqtt_cfg[k] = float(data[k])
|
State.mqtt_cfg[k] = float(data[k])
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
for k in ("billing_day", "billing_month"):
|
for k in ("billing_day", "billing_month"):
|
||||||
if k in data:
|
if k in data and data[k] is not None:
|
||||||
|
try:
|
||||||
State.mqtt_cfg[k] = int(data[k])
|
State.mqtt_cfg[k] = int(data[k])
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
for k in ("tariff_type", "spot_country"):
|
for k in ("tariff_type", "spot_country"):
|
||||||
if k in data:
|
if k in data and data[k] is not None:
|
||||||
State.mqtt_cfg[k] = str(data[k])
|
State.mqtt_cfg[k] = str(data[k])
|
||||||
if "spot_chart" in data:
|
if "spot_chart" in data:
|
||||||
State.mqtt_cfg["spot_chart"] = bool(data["spot_chart"])
|
State.mqtt_cfg["spot_chart"] = bool(data["spot_chart"])
|
||||||
if "billing_tracker_enabled" in data:
|
if "billing_tracker_enabled" in data:
|
||||||
State.mqtt_cfg["billing_tracker_enabled"] = bool(data["billing_tracker_enabled"])
|
State.mqtt_cfg["billing_tracker_enabled"] = bool(data["billing_tracker_enabled"])
|
||||||
for k in ("monthly_rate_eur", "grundpreis_eur_per_month"):
|
|
||||||
if k in data:
|
|
||||||
State.mqtt_cfg[k] = float(data[k])
|
|
||||||
save_config()
|
save_config()
|
||||||
threading.Thread(target=_restart_all, daemon=True).start()
|
threading.Thread(target=_restart_all, daemon=True).start()
|
||||||
return jsonify({"ok": True})
|
return jsonify({"ok": True})
|
||||||
@@ -569,8 +572,8 @@ def api_period_energy():
|
|||||||
pv_total = entry.get("total_energy_total")
|
pv_total = entry.get("total_energy_total")
|
||||||
grid_exp = entry.get("grid_export_kwh")
|
grid_exp = entry.get("grid_export_kwh")
|
||||||
bat_dch = entry.get("bat_discharge_total")
|
bat_dch = entry.get("bat_discharge_total")
|
||||||
if pv_total is not None and grid_exp is not None:
|
if pv_total is not None:
|
||||||
savings = round(max(0.0, pv_total - grid_exp), 2)
|
savings = round(max(0.0, pv_total - (grid_exp or 0.0)), 2)
|
||||||
entry["savings_kwh"] = savings
|
entry["savings_kwh"] = savings
|
||||||
entry["savings_eur"] = round(savings * eff_price, 2)
|
entry["savings_eur"] = round(savings * eff_price, 2)
|
||||||
elif bat_dch is not None:
|
elif bat_dch is not None:
|
||||||
|
|||||||
@@ -1319,8 +1319,8 @@ async function savePrices() {
|
|||||||
spot_markup: parseFloat(document.getElementById("cfg-spot-markup").value || 0),
|
spot_markup: parseFloat(document.getElementById("cfg-spot-markup").value || 0),
|
||||||
spot_country: document.getElementById("cfg-spot-country").value,
|
spot_country: document.getElementById("cfg-spot-country").value,
|
||||||
spot_chart: document.getElementById("cfg-spot-chart").checked,
|
spot_chart: document.getElementById("cfg-spot-chart").checked,
|
||||||
billing_day: parseInt(document.getElementById("cfg-billing-day").value),
|
billing_day: parseInt(document.getElementById("cfg-billing-day").value) || 1,
|
||||||
billing_month: parseInt(document.getElementById("cfg-billing-month").value),
|
billing_month: parseInt(document.getElementById("cfg-billing-month").value) || 1,
|
||||||
billing_tracker_enabled: document.getElementById("cfg-billing-tracker").checked,
|
billing_tracker_enabled: document.getElementById("cfg-billing-tracker").checked,
|
||||||
monthly_rate_eur: parseFloat(document.getElementById("cfg-monthly-rate").value || 0),
|
monthly_rate_eur: parseFloat(document.getElementById("cfg-monthly-rate").value || 0),
|
||||||
grundpreis_eur_per_month: parseFloat(document.getElementById("cfg-grundpreis").value || 0),
|
grundpreis_eur_per_month: parseFloat(document.getElementById("cfg-grundpreis").value || 0),
|
||||||
|
|||||||
Reference in New Issue
Block a user