Jalousien waehrend der Fahrt nachfuehren

actor_states.current_value schrieb bisher nur der AutoAction-Runner fort,
und der fragt die Tahoma-Box alle fuenf Minuten ab (poll_tahoma). Nach
einem Fahrbefehl stand im Raum-Modal deshalb bis zu fuenf Minuten lang
der Stand von vor der Fahrt.

Das Modal verfolgt die Jalousie jetzt selbst: alle zwei Sekunden fragt es
ueber ajax/room.php?action=jalousie genau dieses eine Geraet, zieht die
beiden Regler und das Lamellenbild nach und hoert auf, sobald die Box
keinen Fahrbefehl mehr meldet. Der gelesene Stand landet dabei gleich in
actor_states, damit auch das naechste Oeffnen und der Automatik-Editor
ihn haben. Wer gerade selbst am Schieber zieht, behaelt ihn.

Drei Dinge mussten dafuer aus dem Weg:

- Die Sitzung. helper.php startet sie und schliesst sie nie, PHP sperrt
  ihre Datei bis zum Ende der Anfrage. Ein "Zu" wartet ueber eine Minute
  auf das Ende der Fahrt - solange stand jede weitere Anfrage desselben
  Browsers still. ajax/room.php gibt sie jetzt frei, sobald checkLogin()
  durch ist; danach wird $_SESSION nur noch gelesen.
- Drei Abfragen je Warterunde. warteAufJalousie() holte MovingState,
  Neigung und Position einzeln, obwohl eine Abfrage die ganze Liste
  liefert. Jetzt eine.
- Kein Ort, an dem der frische Stand haengenbleibt. Dafuer
  tahomaZustaende(), tahomaZustaendeSchreiben() und tahomaAktorUrl().

Wahrheitswerte werden dabei als "True"/"False" geschrieben - so macht es
der Runner mit str(), und zwei Schreibweisen fuer denselben Zustand
waeren schlimmer als eine schraege.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-05 12:18:04 +02:00
co-authored by Claude Opus 5
parent 958408eba9
commit 8914133d01
3 changed files with 244 additions and 8 deletions
+33
View File
@@ -30,6 +30,14 @@ if (!checkLogin()) {
exit;
}
// Die Sitzung wird ab hier nur noch gelesen, und PHP haelt ihre Datei bis
// zum Ende der Anfrage exklusiv gesperrt. Ein "Zu" an einer Jalousie wartet
// weiter unten ueber eine Minute auf das Ende der Fahrt - solange stand jede
// weitere Anfrage desselben Browsers still, auch die, die waehrend der Fahrt
// nachsehen will, wie weit sie ist. Alle Schreibzugriffe auf $_SESSION
// stecken in checkLogin() und sind hier durch.
session_write_close();
function raumAntwort($data, $code = 200)
{
http_response_code($code);
@@ -71,6 +79,31 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$mqtt->close();
raumAntwort(["ok" => "Solltemperatur " . $temp . " °C"]);
}
// Eine Jalousie waehrend ihrer Fahrt nachfuehren. actor_states wird
// sonst nur vom Runner fortgeschrieben, und der fragt die Box alle
// fuenf Minuten ab - so lange stand nach einem Fahrbefehl der alte
// Wert im Modal. Hier wird genau ein Geraet gelesen, das kostet die
// Box wenig, und der frische Stand landet gleich in der Tabelle.
if (($_GET["action"] ?? "") === "jalousie") {
$url = tahomaAktorUrl(intval($body["actor"] ?? 0));
if ($url === null) {
raumAntwort(["error" => "Kein Tahoma-Gerät mit dieser Nummer."], 404);
}
$zustaende = tahomaZustaende($url);
if ($zustaende === null) {
raumAntwort(["error" => "Tahoma-Box antwortet nicht."], 503);
}
tahomaZustaendeSchreiben($url, $zustaende);
$zahl = function ($feld) use ($zustaende) {
return isset($zustaende[$feld]) && is_numeric($zustaende[$feld])
? intval($zustaende[$feld]) : null;
};
raumAntwort([
"faehrt" => ($zustaende["core:MovingState"] ?? null) === true,
"position" => $zahl("core:ClosureState"),
"neigung" => $zahl("core:SlateOrientationState"),
]);
}
raumAntwort(["error" => "Unbekannte Aktion."], 400);
} catch (InvalidArgumentException $e) {
raumAntwort(["error" => $e->getMessage()], 400);