Ende der Fahrt abwarten, Umweg an die Hoehe binden

Zwei Sachen, beide an der Anlage aufgefallen.

Abgebrochen wurde auf "core:MovingState ist false". Das ist nicht
dasselbe wie "steht": die Box meldet das Ende der Fahrt, bevor Hoehe und
Neigung darauf nachgezogen haben, und der festgehaltene Wert war dann der
von kurz davor. Statt einer festen Wartezeit zaehlt jetzt Stabilitaet -
fertig ist es, wenn zwei Abfragen hintereinander dasselbe sagen. Damit
faellt auch die Bestaetigungsrunde weg, sie war genau dieser Gedanke in
schlechter.

Der Umweg der Kugelschreiber-Mechanik hing am Neigungswert (ueber 30 %).
Er gehoert an die Hoehe: eine Hoehenfahrt rastet die Lamellen um, danach
muss die Neigung ueber 0 % wieder angefahren werden - bei jedem Winkel,
nicht erst bei grossen. Wird dagegen nur die Neigung verstellt, steht die
Mechanik schon richtig und es geht direkt. NEIGUNG_DIREKT_MAX faellt
damit weg.

Der Hoehenregler im Raum-Modal schickt deshalb jetzt das kombinierte
Kommando mit der Stellung des Neigungsreglers daneben - ohne
Neigungsziel gaebe es nichts, was der Umweg anfahren koennte.

Geprueft an der Wozi-Schiebetuer: Hoehe von 48 auf 60 bei Neigung 76, und
die 76 standen danach wieder da. Vorher htte die Mechanik sie auf einen
beliebigen Wert umgerastet. Dazu elf Faelle im Browser und sieben gegen
transports.py, darunter "Position+Neigung 10" (Umweg) gegen "nur Neigung
80" (direkt).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-05 13:35:38 +02:00
co-authored by Claude Opus 5
parent fe73517c17
commit fe8602a79f
3 changed files with 128 additions and 45 deletions
+35 -25
View File
@@ -27,24 +27,13 @@ const MQTT_BROKER = "localhost";
const MQTT_PORT = 1883;
/**
* Bis zu dieser Neigung fahren die Aussenjalousien direkt.
* So heissen die beiden Parameter einer Jalousie im Geraetemodell.
*
* Sie haben eine Kugelschreiber-Mechanik: beim Herunterfahren stehen die
* Lamellen bei etwa 30 %. In Richtung 0 % laesst sich von jeder Stellung aus
* direkt neigen; ueber 30 % hinaus muss die Mechanik erst einmal auf 0 %
* zurueck, sonst rastet sie nicht um. Ein "Neigung 80 %" ohne diesen Umweg
* bleibt wirkungslos.
*
* Das gilt fuer jedes Kommando, das die Neigung setzt - "Neigung" ebenso wie
* "Position+Neigung". Erkannt wird es deshalb am Parameter und nicht am
* Kommandonamen: beide heissen ihren Neigungsparameter "Neigung".
*
* Dasselbe steht in SolarManager/autoActions/transports.py - beide Versender
* brauchen es, und beide muessen es wissen.
* An ihnen wird die Kugelschreiber-Mechanik erkannt, nicht am Kommandonamen:
* setzt ein Befehl beide, war eine Hoehenfahrt dabei und die Lamellen sind
* umgerastet - dann muss die Neigung ueber 0 % angefahren werden (siehe
* sendeTahoma()). Setzt er nur die Neigung, steht die Mechanik schon richtig.
*/
const NEIGUNG_DIREKT_MAX = 30;
/** So heissen die beiden Parameter einer Jalousie im Geraetemodell. */
const NEIGUNG_PARAMETER = "Neigung";
const POSITION_PARAMETER = "Position";
@@ -485,6 +474,7 @@ function tahomaNachlesen($deviceUrl)
$start = time();
$gestartet = false;
$zustaende = null;
$letzterStand = null;
while (time() - $start < JALOUSIE_WARTE_SEKUNDEN) {
sleep(2);
$gelesen = tahomaZustaende($deviceUrl);
@@ -492,11 +482,21 @@ function tahomaNachlesen($deviceUrl)
continue;
}
$zustaende = $gelesen;
if (($zustaende["core:MovingState"] ?? null) === true) {
$faehrt = ($zustaende["core:MovingState"] ?? null) === true;
// "faehrt nicht mehr" ist nicht "steht": die Box meldet das Ende der
// Fahrt, bevor Hoehe und Neigung darauf nachgezogen haben. Erst zwei
// gleiche Ablesungen hintereinander sind der Endstand.
$stand = $faehrt ? null
: strval($zustaende["core:ClosureState"] ?? "")
. "/" . strval($zustaende["core:SlateOrientationState"] ?? "");
$steht = $stand !== null && $stand === $letzterStand;
$letzterStand = $stand;
if ($faehrt) {
$gestartet = true;
continue;
}
if ($gestartet || time() - $start >= JALOUSIE_VORLAUF_SEKUNDEN) {
if ($steht && ($gestartet || time() - $start >= JALOUSIE_VORLAUF_SEKUNDEN)) {
break;
}
}
@@ -580,13 +580,23 @@ function sendeTahoma($cmd, $werte, $probe)
$neigungIndex = 1;
}
// Kugelschreiber-Mechanik: ueber NEIGUNG_DIREKT_MAX hinaus rastet sie nur
// um, wenn sie vorher einmal auf 0 % war. Geschickt wird deshalb derselbe
// Befehl zweimal - erst mit Neigung 0, dann mit dem gewuenschten Wert.
// Die Position bleibt dabei stehen, die Jalousie faehrt also nur einmal.
$umweg = $neigungIndex !== null
&& is_numeric($parameter[$neigungIndex])
&& $parameter[$neigungIndex] > NEIGUNG_DIREKT_MAX;
// Kugelschreiber-Mechanik: eine Hoehenfahrt setzt die Lamellen um, und aus
// der neuen Raststellung heraus laesst sich die Neigung nicht direkt
// anfahren - die Mechanik muss dafuer erst einmal auf 0 % zurueck.
// Deshalb wird derselbe Befehl zweimal geschickt, erst mit Neigung 0,
// dann mit dem gewuenschten Wert; die Position bleibt dabei stehen, die
// Jalousie faehrt also nur einmal.
//
// Der Umweg gehoert an die Hoehe, nicht an den Neigungswert: setzt ein
// Befehl beides, wird er immer gefahren, auch bei kleinen Winkeln. Wird
// nur die Neigung verstellt, steht die Mechanik schon richtig und es geht
// direkt. Ein Befehl, der nur die Hoehe setzt, hat kein Neigungsziel -
// fuer den gibt es hier nichts zu tun; das Raum-Modal schickt deshalb
// beides zusammen (siehe zeichneBeschattung() in roomControls.php).
//
// Dasselbe steht in transports.py: beide Versender brauchen es.
$umweg = $neigungIndex !== null && $positionIndex !== null
&& is_numeric($parameter[$neigungIndex]);
$vorstufe = $parameter;
if ($umweg) {