Haltezeit als Zeitfeld: Stunden und Minuten statt einer Minutenzahl
Dasselbe <input type="time"> wie von/bis daneben, nur als Dauer gelesen -
"03:30" tippt sich leichter als "210" und steht in derselben Zeile wie die
beiden Uhrzeiten darueber. Dass es keine Uhrzeit meint, sagt der Text
ringsum ("erst nach ... am Stueck"); die Kopfzeile des Rahmens schreibt es
beim Tippen aus.
Die Obergrenze ist damit 23:59 statt 24 Stunden - genau das, was ein
Zeitfeld hergibt.
Dabei aufgefallen: haltezeitKurz() rundete auf Zehntelstunden und machte aus
23:59 die Auskunft "24 Std.". Eine Haltezeit, die laenger aussieht als sie
ist, ist genau die falsche Auskunft - krumme Werte stehen jetzt als
"23 Std. 59 Min." da, halbe behalten ihr Komma.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+11
-8
@@ -469,18 +469,21 @@ $nutzdaten = json_encode([
|
||||
benutzen - Zeit - und trotzdem entgegengesetzt wirken: die Sperre
|
||||
bremst die Wiederholung, die Haltezeit den ersten Lauf.
|
||||
|
||||
Freie Minuten statt einer Auswahlliste: Wonach man sucht, haengt am
|
||||
Messwert. Die Zeile über dem Rahmen rechnet beim Tippen mit und
|
||||
zeigt "erst nach 3,5 Std." - dort steht die lesbare Fassung, hier
|
||||
die eingebbare.
|
||||
Frei einstellbar statt aus einer Auswahlliste: Wonach man sucht,
|
||||
hängt am Messwert - eine offene Tür fällt nach zwei Minuten auf,
|
||||
ein laufender Wasserhahn erst nach Stunden.
|
||||
|
||||
Dasselbe Zeitfeld wie von/bis darüber, nur als Dauer gelesen. Dass
|
||||
es keine Uhrzeit meint, sagt der Text ringsum ("erst nach … am
|
||||
Stück"); die Zeile über dem Rahmen schreibt es beim Tippen aus
|
||||
("erst nach 3,5 Std.").
|
||||
-->
|
||||
<div class="col-sm-6">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">Auslösen erst nach</span>
|
||||
<input type="number" class="form-control" id="holdMin"
|
||||
min="0" max="1440" step="5" value="0"
|
||||
title="So lange muss die Bedingung ohne Unterbrechung erfüllt sein. 0 = sofort.">
|
||||
<span class="input-group-text">Min. am Stück</span>
|
||||
<input type="time" class="form-control" id="holdZeit" value="00:00"
|
||||
title="Stunden und Minuten, die die Bedingung ohne Unterbrechung erfüllt sein muss. 00:00 = sofort.">
|
||||
<span class="input-group-text">am Stück</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -170,7 +170,7 @@ sonst steht in der Übersicht etwas anderes als im Editor.
|
||||
| `next_day` | Der Rahmen gilt für **morgen** (Vorabend-Form) | Uhrzeit und Fenster bleiben bei heute |
|
||||
| `window_from`/`window_to` | Zeitfenster; `von > bis` heißt über Mitternacht | |
|
||||
| `lockout_secs` | Sperrzeit nach einem Lauf (0 / 60 / 900) | |
|
||||
| `hold_secs` | Haltezeit: so lange muss die Bedingung **ununterbrochen** erfüllt sein (0 = sofort, frei in Minuten bis 24 Std.) | Zählt im Speicher des Runners — ein Neustart fängt die Zeit von vorn an |
|
||||
| `hold_secs` | Haltezeit: so lange muss die Bedingung **ununterbrochen** erfüllt sein (0 = sofort, frei als Stunden:Minuten bis 23:59) | Zählt im Speicher des Runners — ein Neustart fängt die Zeit von vorn an |
|
||||
| `once_per_day` | höchstens ein Lauf je Kalendertag | |
|
||||
| `force_once` | am Ende des Fensters notfalls doch ausführen | greift nur, wenn im Fenster gar nichts lief |
|
||||
|
||||
@@ -448,5 +448,5 @@ räumt der Runner selbst weg.
|
||||
| … verstehen, warum etwas lief | `automation_log`, dann die Zeitleiste des Tages (→ [zeitleiste.md](zeitleiste.md)) |
|
||||
| … das Nachholfenster ändern | `catchup_minutes` in `config.ini` des Runners |
|
||||
| … eine weitere Stufe für die Sperre | `lockoutChoices()` in `restricted/automations.php` — eine Zeile, der Rest zieht nach |
|
||||
| … die Grenzen der Haltezeit ändern | `haltezeitPruefen()` in `restricted/automations.php` **und** `max` am Feld `holdMin` |
|
||||
| … die Grenzen der Haltezeit ändern | `haltezeitPruefen()` in `restricted/automations.php` **und** `haltezeitAusUhr()` im Editor |
|
||||
| … auf Dauerzustände reagieren (Wasser läuft, Tür steht offen) | Haltezeit im Rahmen, dazu eine Aktion des Geräts „Benachrichtigungen“ (→ [benachrichtigungen.md](benachrichtigungen.md)) |
|
||||
|
||||
+36
-13
@@ -1136,10 +1136,36 @@ function rahmenKurzText() {
|
||||
return teile.join(" · ");
|
||||
}
|
||||
|
||||
/** Wie haltezeitKurz() in automations.php: Minuten bis eine Stunde, dann Stunden. */
|
||||
/**
|
||||
* Haltezeit und Zeitfeld ineinander umrechnen.
|
||||
*
|
||||
* Das Feld ist ein gewoehnliches <input type="time">, sein Wert also "03:30".
|
||||
* Gemeint ist keine Uhrzeit, sondern eine Dauer - deshalb hier zwei eigene
|
||||
* Funktionen und nicht die Behandlung von window_from/window_to, die den Text
|
||||
* unveraendert durchreichen.
|
||||
*/
|
||||
function haltezeitAlsUhr(sekunden) {
|
||||
const min = Math.round(sekunden / 60);
|
||||
return String(Math.floor(min / 60)).padStart(2, "0") + ":"
|
||||
+ String(min % 60).padStart(2, "0");
|
||||
}
|
||||
|
||||
/** Leer oder unsinnig ist 0; die Obergrenze ist 23:59, siehe haltezeitPruefen(). */
|
||||
function haltezeitAusUhr(text) {
|
||||
const teile = String(text || "").split(":");
|
||||
const sek = ((Number(teile[0]) || 0) * 60 + (Number(teile[1]) || 0)) * 60;
|
||||
return Math.min(Math.max(sek, 0), 86340);
|
||||
}
|
||||
|
||||
/** Wie haltezeitKurz() in automations.php - dort steht, warum nicht gerundet wird. */
|
||||
function haltezeitKurz(sekunden) {
|
||||
if (sekunden < 3600) return Math.floor(sekunden / 60) + " Min.";
|
||||
return (sekunden / 3600).toFixed(1).replace(/[.,]0$/, "").replace(".", ",") + " Std.";
|
||||
const minuten = Math.floor(sekunden / 60);
|
||||
if (minuten < 60) return minuten + " Min.";
|
||||
const stunden = Math.floor(minuten / 60);
|
||||
const rest = minuten % 60;
|
||||
if (rest === 0) return stunden + " Std.";
|
||||
if (rest === 30) return stunden + ",5 Std.";
|
||||
return stunden + " Std. " + rest + " Min.";
|
||||
}
|
||||
|
||||
function rahmenIstVorgabe() {
|
||||
@@ -1181,7 +1207,7 @@ function fuelleFormular() {
|
||||
const sperre = document.getElementById("lockoutSecs");
|
||||
optionListe(sperre, autoLockouts.map(o => ({ value: o.value, text: o.label })),
|
||||
autoModel.lockout_secs);
|
||||
document.getElementById("holdMin").value = autoModel.hold_secs / 60;
|
||||
document.getElementById("holdZeit").value = haltezeitAlsUhr(autoModel.hold_secs);
|
||||
document.getElementById("autoName").value = autoModel.name;
|
||||
// Kennt die Liste die Etage nicht, bleibt eine Auswahlliste sonst leer
|
||||
// stehen und schickt beim Speichern "" mit.
|
||||
@@ -1216,10 +1242,7 @@ function leseFormular() {
|
||||
autoModel.once_per_day = document.getElementById("oncePerDay").checked;
|
||||
autoModel.next_day = document.getElementById("nextDay").checked;
|
||||
autoModel.lockout_secs = Number(document.getElementById("lockoutSecs").value);
|
||||
// Minuten im Feld, Sekunden im Modell - und nichts Unmoegliches: ein
|
||||
// leeres Feld ist 0, ein Tag ist die Obergrenze (siehe haltezeitPruefen()).
|
||||
const halten = Math.round(Number(document.getElementById("holdMin").value) || 0);
|
||||
autoModel.hold_secs = Math.min(Math.max(halten, 0), 1440) * 60;
|
||||
autoModel.hold_secs = haltezeitAusUhr(document.getElementById("holdZeit").value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1227,15 +1250,15 @@ function leseFormular() {
|
||||
* Ohne das stuende dort "rund um die Uhr", waehrend darunter 08:45 steht.
|
||||
*/
|
||||
function rahmenFelderVerdrahten() {
|
||||
["tSpanFrom", "tSpanTo", "lockoutSecs", "holdMin",
|
||||
["tSpanFrom", "tSpanTo", "lockoutSecs", "holdZeit",
|
||||
"runOnce", "oncePerDay", "nextDay"].forEach(id => {
|
||||
const feld = document.getElementById(id);
|
||||
if (feld) feld.addEventListener("change", () => { leseFormular(); renderRahmen(); });
|
||||
});
|
||||
// Bei der Haltezeit schon beim Tippen: aus "210" wird in der Kopfzeile
|
||||
// "erst nach 3,5 Std." - genau dafuer gibt man die Zahl ein. "change"
|
||||
// allein kaeme erst beim Verlassen des Feldes.
|
||||
document.getElementById("holdMin")
|
||||
// Bei der Haltezeit schon beim Tippen: aus "03:30" wird in der Kopfzeile
|
||||
// "erst nach 3,5 Std.". "change" allein kaeme erst beim Verlassen des
|
||||
// Feldes, und ein Zeitfeld verlaesst man ungern, um nachzusehen.
|
||||
document.getElementById("holdZeit")
|
||||
.addEventListener("input", () => { leseFormular(); renderRahmen(); });
|
||||
|
||||
// Zugeklappt steht in der Kopfzeile, was gilt; aufgeklappt stehen dort die
|
||||
|
||||
+24
-13
@@ -232,11 +232,12 @@ function lockoutChoices()
|
||||
* Wasserhahn erst nach Stunden. Eine Stufenliste traefe immer nur die Haelfte
|
||||
* der Faelle.
|
||||
*
|
||||
* Grenzen gibt es trotzdem. Unter null ist keine Zeit; oberhalb eines Tages
|
||||
* Grenzen gibt es trotzdem. Unter null ist keine Zeit; oberhalb von 23:59
|
||||
* waere es keine Haltezeit mehr, sondern ein Dauerzustand, den man besser
|
||||
* anders abfragt - und das Zeitfenster schneidet sie ohnehin ab. Gerechnet
|
||||
* wird in ganzen Minuten, weil der Editor Minuten anbietet und Sekunden hier
|
||||
* nichts gewinnen: die Messwerte kommen viel seltener.
|
||||
* anders abfragt - und das Zeitfenster schneidet sie ohnehin ab. Die Obergrenze
|
||||
* ist genau das, was ein Zeitfeld hergibt. Gerechnet wird in ganzen Minuten,
|
||||
* weil der Editor Stunden und Minuten anbietet und Sekunden hier nichts
|
||||
* gewinnen: die Messwerte kommen viel seltener.
|
||||
*/
|
||||
function haltezeitPruefen($sekunden)
|
||||
{
|
||||
@@ -244,26 +245,36 @@ function haltezeitPruefen($sekunden)
|
||||
if ($sekunden < 0) {
|
||||
$sekunden = 0;
|
||||
}
|
||||
if ($sekunden > 86400) {
|
||||
$sekunden = 86400;
|
||||
if ($sekunden > 86340) { // 23:59, mehr kann das Zeitfeld nicht
|
||||
$sekunden = 86340;
|
||||
}
|
||||
return intdiv($sekunden, 60) * 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eine Haltezeit in Worten - "45 Min.", "1 Std.", "3,5 Std."
|
||||
* Eine Haltezeit in Worten - "45 Min.", "1 Std.", "3,5 Std.", "23 Std. 59 Min."
|
||||
*
|
||||
* Minuten bis eine Stunde, darueber Stunden: "210 Min." muss man umrechnen,
|
||||
* "3,5 Std." nicht. Die Nachkommastelle faellt weg, wenn sie null ist.
|
||||
* "3,5 Std." nicht. Halbe Stunden bekommen ihr Komma, alles andere Krumme die
|
||||
* Minuten ausgeschrieben - gerundet wird nicht. Aus 23:59 wurde sonst
|
||||
* "24 Std.", und eine Haltezeit, die laenger aussieht als sie ist, waere
|
||||
* genau die falsche Auskunft.
|
||||
*/
|
||||
function haltezeitKurz($sekunden)
|
||||
{
|
||||
$sekunden = intval($sekunden);
|
||||
if ($sekunden < 3600) {
|
||||
return intdiv($sekunden, 60) . " Min.";
|
||||
$minuten = intdiv(intval($sekunden), 60);
|
||||
if ($minuten < 60) {
|
||||
return $minuten . " Min.";
|
||||
}
|
||||
$zahl = number_format($sekunden / 3600, 1, ",", "");
|
||||
return rtrim(rtrim($zahl, "0"), ",") . " Std.";
|
||||
$stunden = intdiv($minuten, 60);
|
||||
$rest = $minuten % 60;
|
||||
if ($rest === 0) {
|
||||
return $stunden . " Std.";
|
||||
}
|
||||
if ($rest === 30) {
|
||||
return $stunden . ",5 Std.";
|
||||
}
|
||||
return $stunden . " Std. " . $rest . " Min.";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user