Automatiken: Rahmen am Vorabend fuer den folgenden Tag
Neuer Schalter "Am Vorabend" im Wann-Band (Spalte next_day). Wochentage, Ferien und Feiertage gelten dann fuer morgen: "Kinderrollos zu, wenn morgen Schule ist" ist Mo-Fr, Ferien nie, Feiertage nie - wie der Wecker. Mit dem heutigen Tag ging das am letzten Ferientag, am Abend vor einem Feiertag und am Abend eines Feiertags daneben. Editor-Satz, Kurzfassung und Uebersicht nennen den Vorabend vorne, damit auch "nicht an Feiertagen" als Folgetag gelesen wird. Die Spalte legt vorabend.sql im SolarManager an, ausgewertet wird sie im Runner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -200,6 +200,11 @@ if ($action === "list") {
|
||||
} else {
|
||||
$wann = "nie – kein Tag ausgewählt";
|
||||
}
|
||||
// Vorabend: alle Tagesangaben meinen morgen. Vorne, damit auch
|
||||
// "nicht an Feiertagen" weiter hinten als Folgetag gelesen wird.
|
||||
if ($a["next_day"]) {
|
||||
$wann = "Vorabend von " . $wann;
|
||||
}
|
||||
if ($a["window_from"] !== "00:00" || $a["window_to"] !== "23:59") {
|
||||
$wann .= ", " . $a["window_from"] . "–" . $a["window_to"];
|
||||
}
|
||||
@@ -405,6 +410,16 @@ $nutzdaten = json_encode([
|
||||
<div class="btn-group btn-group-sm" role="group" id="feiertagGroup"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Vorabend: fuer alles, was abends fuer morgen geschieht - "Kinder
|
||||
ins Bett, wenn morgen Schule ist" ist dann Mo-Fr, Ferien nie,
|
||||
Feiertage nie, wie der Wecker. Uhrzeit und Zeitfenster bleiben
|
||||
beim heutigen Tag. -->
|
||||
<div class="form-check mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="nextDay">
|
||||
<label class="form-check-label" for="nextDay">
|
||||
Am Vorabend – Wochentage, Ferien und Feiertage gelten für den folgenden Tag
|
||||
</label>
|
||||
</div>
|
||||
<!--
|
||||
.callout ist ein AdminLTE-Bauteil: farbiger Balken links, getoenter
|
||||
Grund, und die Toene kommen aus Bootstraps *-bg-subtle-Variablen -
|
||||
|
||||
@@ -36,6 +36,7 @@ CREATE TABLE IF NOT EXISTS `automations` (
|
||||
`weekdays` tinyint(3) unsigned NOT NULL DEFAULT 127 COMMENT 'Bitmaske: Bit 0 = Montag ... Bit 6 = Sonntag',
|
||||
`on_vacation` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Auch in den Ferien ausfuehren',
|
||||
`on_holiday` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Auch an Feiertagen ausfuehren',
|
||||
`next_day` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Wochentage, Ferien und Feiertage gelten fuer morgen (Vorabend). Nachgeruestet mit vorabend.sql im SolarManager',
|
||||
`force_once` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Am Ende des Zeitraums auf jeden Fall ausfuehren',
|
||||
`lockout_secs` int(11) NOT NULL DEFAULT 60 COMMENT 'Sperrzeit: so lange nach einer Ausloesung wird nicht erneut geschaltet. Gegen Messwerte, die um die Schwelle pendeln - jedes Ueberschreiten waere sonst eine echte Flanke. Der Editor bietet 0, 60 und 900 an',
|
||||
`cond_met` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'War die Bedingung beim letzten Durchlauf erfuellt? Nur die steigende Flanke loest aus, sonst wuerde Temperatur groesser 22 im Sekundentakt feuern',
|
||||
|
||||
@@ -1100,6 +1100,9 @@ function rahmenText() {
|
||||
if (dazu.length && tage !== 127) satz += ", dazu " + aufzaehlung(dazu);
|
||||
}
|
||||
if (verbote.length) satz += ", aber nicht " + aufzaehlung(verbote);
|
||||
// Vorabend: derselbe Satz, nur fuer morgen gerechnet. Vorne, damit auch
|
||||
// "aber nicht an Feiertagen" als Folgetag gelesen wird.
|
||||
if (autoModel.next_day) satz = satz.replace(/^Läuft /, "Läuft am Vortag, gerechnet für den Folgetag: ");
|
||||
return satz + ".";
|
||||
}
|
||||
|
||||
@@ -1112,6 +1115,7 @@ function rahmenText() {
|
||||
*/
|
||||
function rahmenKurzText() {
|
||||
const teile = [tageText(autoModel.weekdays) || "an keinem Tag"];
|
||||
if (autoModel.next_day) teile[0] = "Vorabend von " + teile[0];
|
||||
if (autoModel.on_vacation === 0) teile.push("nicht in den Ferien");
|
||||
if (autoModel.on_vacation === 2) teile.push("dazu Ferientage");
|
||||
if (autoModel.on_holiday === 0) teile.push("nicht an Feiertagen");
|
||||
@@ -1133,6 +1137,7 @@ function rahmenIstVorgabe() {
|
||||
return autoModel.weekdays === 127
|
||||
&& autoModel.on_vacation === 1
|
||||
&& autoModel.on_holiday === 1
|
||||
&& !autoModel.next_day
|
||||
&& autoModel.window_from === "00:00"
|
||||
&& autoModel.window_to === "23:59"
|
||||
&& !autoModel.once_per_day
|
||||
@@ -1179,6 +1184,7 @@ function fuelleFormular() {
|
||||
document.getElementById("tSpanTo").value = autoModel.window_to;
|
||||
document.getElementById("runOnce").checked = autoModel.force_once;
|
||||
document.getElementById("oncePerDay").checked = autoModel.once_per_day;
|
||||
document.getElementById("nextDay").checked = autoModel.next_day;
|
||||
renderRahmen();
|
||||
rahmenFelderVerdrahten();
|
||||
renderConditions();
|
||||
@@ -1197,6 +1203,7 @@ function leseFormular() {
|
||||
// sofort nachziehen muss.
|
||||
autoModel.force_once = document.getElementById("runOnce").checked;
|
||||
autoModel.once_per_day = document.getElementById("oncePerDay").checked;
|
||||
autoModel.next_day = document.getElementById("nextDay").checked;
|
||||
autoModel.lockout_secs = Number(document.getElementById("lockoutSecs").value);
|
||||
}
|
||||
|
||||
@@ -1205,7 +1212,7 @@ function leseFormular() {
|
||||
* Ohne das stuende dort "rund um die Uhr", waehrend darunter 08:45 steht.
|
||||
*/
|
||||
function rahmenFelderVerdrahten() {
|
||||
["tSpanFrom", "tSpanTo", "lockoutSecs", "runOnce", "oncePerDay"].forEach(id => {
|
||||
["tSpanFrom", "tSpanTo", "lockoutSecs", "runOnce", "oncePerDay", "nextDay"].forEach(id => {
|
||||
const feld = document.getElementById(id);
|
||||
if (feld) feld.addEventListener("change", () => { leseFormular(); renderRahmen(); });
|
||||
});
|
||||
@@ -1250,6 +1257,7 @@ function loadAutomatic() {
|
||||
weekdays: a.weekdays,
|
||||
on_vacation: a.on_vacation,
|
||||
on_holiday: a.on_holiday,
|
||||
next_day: !!a.next_day,
|
||||
force_once: a.force_once,
|
||||
once_per_day: a.once_per_day,
|
||||
lockout_secs: a.lockout_secs,
|
||||
@@ -1338,6 +1346,7 @@ function submitAutoAction() {
|
||||
weekdays: autoModel.weekdays,
|
||||
on_vacation: autoModel.on_vacation,
|
||||
on_holiday: autoModel.on_holiday,
|
||||
next_day: autoModel.next_day,
|
||||
force_once: autoModel.force_once,
|
||||
once_per_day: autoModel.once_per_day,
|
||||
lockout_secs: autoModel.lockout_secs,
|
||||
|
||||
+15
-10
@@ -803,6 +803,7 @@ function emptyAutomation($floor)
|
||||
"weekdays" => 127,
|
||||
"on_vacation" => 1,
|
||||
"on_holiday" => 1,
|
||||
"next_day" => false,
|
||||
"force_once" => false,
|
||||
"once_per_day" => false,
|
||||
"lockout_secs" => 60,
|
||||
@@ -835,6 +836,9 @@ function loadAutomation($id)
|
||||
"weekdays" => intval($row["weekdays"]),
|
||||
"on_vacation" => intval($row["on_vacation"]),
|
||||
"on_holiday" => intval($row["on_holiday"]),
|
||||
// Vorabend: der Rahmen gilt fuer morgen. Siehe vorabend.sql im
|
||||
// SolarManager; ?? 0 wie bei once_per_day, falls die Spalte fehlt.
|
||||
"next_day" => (bool)($row["next_day"] ?? 0),
|
||||
"force_once" => (bool)$row["force_once"],
|
||||
// ?? 0, damit der Editor auch vor der Migration noch aufgeht:
|
||||
// rahmen_erweitern.sql legt die Spalte erst an.
|
||||
@@ -925,6 +929,7 @@ function saveAutomation($data)
|
||||
$weekdays = intval($data["weekdays"] ?? 127) & 127;
|
||||
$onVacation = kalendertagWert($data["on_vacation"] ?? 1);
|
||||
$onHoliday = kalendertagWert($data["on_holiday"] ?? 1);
|
||||
$nextDay = !empty($data["next_day"]) ? 1 : 0;
|
||||
$forceOnce = !empty($data["force_once"]) ? 1 : 0;
|
||||
$oncePerDay = !empty($data["once_per_day"]) ? 1 : 0;
|
||||
// Nur die angebotenen Stufen, sonst die Vorgabe. Eine krumme Zahl kaeme
|
||||
@@ -957,12 +962,12 @@ function saveAutomation($data)
|
||||
// Zeitstempel, dass er sein Regelwerk neu laden muss.
|
||||
$stmt = $db->prepare("UPDATE automations SET name = ?, floor = ?, enabled = ?,
|
||||
window_from = ?, window_to = ?, weekdays = ?,
|
||||
on_vacation = ?, on_holiday = ?, force_once = ?,
|
||||
on_vacation = ?, on_holiday = ?, next_day = ?, force_once = ?,
|
||||
once_per_day = ?, lockout_secs = ?, changed = NOW()
|
||||
WHERE id = ?");
|
||||
$stmt->bind_param("ssissiiiiiii", $name, $floor, $enabled, $windowFrom, $windowTo,
|
||||
$weekdays, $onVacation, $onHoliday, $forceOnce, $oncePerDay,
|
||||
$lockout, $id);
|
||||
$stmt->bind_param("ssissiiiiiiii", $name, $floor, $enabled, $windowFrom, $windowTo,
|
||||
$weekdays, $onVacation, $onHoliday, $nextDay, $forceOnce,
|
||||
$oncePerDay, $lockout, $id);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
$db->query("DELETE FROM automation_conditions WHERE automation_id = " . $id);
|
||||
@@ -970,12 +975,12 @@ function saveAutomation($data)
|
||||
} else {
|
||||
$stmt = $db->prepare("INSERT INTO automations
|
||||
(name, floor, enabled, window_from, window_to, weekdays,
|
||||
on_vacation, on_holiday, force_once, once_per_day,
|
||||
lockout_secs)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?)");
|
||||
$stmt->bind_param("ssissiiiiii", $name, $floor, $enabled, $windowFrom, $windowTo,
|
||||
$weekdays, $onVacation, $onHoliday, $forceOnce, $oncePerDay,
|
||||
$lockout);
|
||||
on_vacation, on_holiday, next_day, force_once,
|
||||
once_per_day, lockout_secs)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)");
|
||||
$stmt->bind_param("ssissiiiiiii", $name, $floor, $enabled, $windowFrom, $windowTo,
|
||||
$weekdays, $onVacation, $onHoliday, $nextDay, $forceOnce,
|
||||
$oncePerDay, $lockout);
|
||||
$stmt->execute();
|
||||
$id = $db->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
Reference in New Issue
Block a user