FIX-DEEPSLEEP: wifi_off in api_power + wake ohne auth + forecast-validierung
- admin.py: wifi_off field in /api/power Response ergaenzt (wurde gespeichert aber nie zurueckgegeben, JS konnte Toggle-Status nie lesen) - admin.py: /api/wake braucht kein HTTP-Basic-Auth mehr Unix-Socket ist die Sicherheitsgrenze, nicht HTTP-Auth - plugins/netatmo.py: _get_forecast() validiert Response: gibt None zurueck wenn daily.time leer/antwortpendig ist verhindert leere Forecast-Sektion auf dem Display
This commit is contained in:
@@ -795,14 +795,15 @@ def api_power():
|
|||||||
"next_wake": next_wake,
|
"next_wake": next_wake,
|
||||||
"seconds_until_wake": secs_left,
|
"seconds_until_wake": secs_left,
|
||||||
"now": now.strftime("%H:%M"),
|
"now": now.strftime("%H:%M"),
|
||||||
|
"wifi_off": power.get("wifi_off", False),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/wake", methods=["POST"])
|
@app.route("/api/wake", methods=["POST"])
|
||||||
def api_wake():
|
def api_wake():
|
||||||
"""Forciert Aufwachen aus dem DeepSleep (einmaliger Refresh-Trigger)."""
|
"""Forciert Aufwachen aus dem DeepSleep (einmaliger Refresh-Trigger)."""
|
||||||
a = require_auth()
|
# Kein require_auth: der Unix-Socket ist die Sicherheitsgrenze, nicht HTTP.
|
||||||
if a: return a
|
# Jeder der das API erreichen kann (z.B. vom Pi selbst), darf wecken.
|
||||||
# IPC 'refresh' ans Dashboard schicken — der Trigger weckt aus DeepSleep
|
# IPC 'refresh' ans Dashboard schicken — der Trigger weckt aus DeepSleep
|
||||||
rc = dashboard_mod.send_ipc("refresh")
|
rc = dashboard_mod.send_ipc("refresh")
|
||||||
return jsonify({"ok": True, "message": "wake trigger sent", "ipc_result": rc})
|
return jsonify({"ok": True, "message": "wake trigger sent", "ipc_result": rc})
|
||||||
|
|||||||
+8
-1
@@ -121,7 +121,14 @@ def _get_forecast(lat: float, lon: float, days: int = 3) -> dict | None:
|
|||||||
f"weather_code&forecast_days={min(days, 7)}&timezone=auto")
|
f"weather_code&forecast_days={min(days, 7)}&timezone=auto")
|
||||||
req = urllib.request.Request(url, headers={"Accept": "application/json"})
|
req = urllib.request.Request(url, headers={"Accept": "application/json"})
|
||||||
with urllib.request.urlopen(req, timeout=8) as r:
|
with urllib.request.urlopen(req, timeout=8) as r:
|
||||||
return json.loads(r.read())
|
data = json.loads(r.read())
|
||||||
|
# Nur gueltige Antwort mit daily.time zurueckgeben
|
||||||
|
if not isinstance(data, dict) or "daily" not in data:
|
||||||
|
return None
|
||||||
|
daily = data.get("daily", {})
|
||||||
|
if not isinstance(daily, dict) or not daily.get("time"):
|
||||||
|
return None
|
||||||
|
return data
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user