Sperrzeit je Automatik in drei Stufen
Die steigende Flanke allein schuetzt nicht gegen einen Messwert, der um die Schwelle pendelt: "Temperatur > 22" bei 22,1 / 21,9 / 22,1 Grad ist jedes Mal eine echte Flanke, und ueber MQTT koennen die Werte im Sekundentakt hereinkommen. Gemessen: fuenf Kommandos in einer halben Minute. automations.lockout_secs sagt jetzt, wie lange nach einer Ausloesung nicht wieder geschaltet wird. Der Editor bietet drei Stufen an - ohne, eine Minute, eine Viertelstunde -, weil die passende Wahl am Geraet haengt und nicht an einer Zahl: ein Rollladen soll nicht alle zwanzig Sekunden losfahren, eine Lichtfarbe darf das. Gespeichert werden Sekunden, damit eine vierte Stufe eine Zeile in lockoutChoices() ist und keine Wanderung durch die Datenbank. Vorbelegt ist eine Minute. Eine Flanke in der Sperrzeit wird verworfen, nicht aufgehoben. Ein Rollladen, der eine Viertelstunde spaeter doch noch losfaehrt, weil vor langer Zeit einmal eine Schwelle gestreift wurde, waere unangenehmer als einer, der gar nicht faehrt - und der naechste echte Anlass nach Ablauf der Sperre kommt ohnehin durch. Verworfene Flanken stehen auf DEBUG und nicht in automation_log, sonst waere die Tabelle bei einem zappelnden Sensor voll davon. force_once bleibt unberuehrt: es greift nur, wenn im Fenster gar nichts gelaufen ist - dann ist auch keine Sperre aktiv. Nachgemessen am pendelnden Sensor: mit 60 s Sperre ein Kommando, ohne Sperre fuenf. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -79,6 +79,27 @@ function operatorChoices($type)
|
||||
return $liste;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sperrzeit: so lange nach einer Ausloesung wird nicht erneut geschaltet.
|
||||
*
|
||||
* Gedacht gegen Messwerte, die um die Schwelle pendeln - "Temperatur > 22"
|
||||
* bei 22,1 / 21,9 / 22,1 Grad ist jedes Mal eine echte steigende Flanke, und
|
||||
* ohne Sperre ginge jedes Mal ein Kommando raus. Wie schlimm das ist, haengt
|
||||
* am Geraet: ein Rollladen soll nicht alle zwanzig Sekunden losfahren, eine
|
||||
* Lichtfarbe darf das.
|
||||
*
|
||||
* Gespeichert werden Sekunden, angeboten werden nur diese Stufen - eine
|
||||
* vierte ist damit eine Zeile und keine Wanderung durch die Datenbank.
|
||||
*/
|
||||
function lockoutChoices()
|
||||
{
|
||||
return [
|
||||
["value" => 0, "label" => "Ohne – jede Flanke schaltet"],
|
||||
["value" => 60, "label" => "1 Minute – z.B. Licht und Farbe"],
|
||||
["value" => 900, "label" => "15 Minuten – z.B. Rollläden und Ventile"],
|
||||
];
|
||||
}
|
||||
|
||||
/** Wie das Wertfeld im Editor aussieht. */
|
||||
function inputForType($type, $hasOptions)
|
||||
{
|
||||
@@ -254,6 +275,7 @@ function emptyAutomation($floor)
|
||||
"on_vacation" => true,
|
||||
"on_holiday" => true,
|
||||
"force_once" => false,
|
||||
"lockout_secs" => 60,
|
||||
"last_run" => null,
|
||||
"conditions" => [],
|
||||
"actions" => [],
|
||||
@@ -284,6 +306,7 @@ function loadAutomation($id)
|
||||
"on_vacation" => (bool)$row["on_vacation"],
|
||||
"on_holiday" => (bool)$row["on_holiday"],
|
||||
"force_once" => (bool)$row["force_once"],
|
||||
"lockout_secs" => intval($row["lockout_secs"]),
|
||||
"last_run" => $row["last_run"],
|
||||
"conditions" => [],
|
||||
"actions" => [],
|
||||
@@ -367,6 +390,12 @@ function saveAutomation($data)
|
||||
$onVacation = !empty($data["on_vacation"]) ? 1 : 0;
|
||||
$onHoliday = !empty($data["on_holiday"]) ? 1 : 0;
|
||||
$forceOnce = !empty($data["force_once"]) ? 1 : 0;
|
||||
// Nur die angebotenen Stufen, sonst die Vorgabe. Eine krumme Zahl kaeme
|
||||
// hier nur aus einer selbstgebauten Anfrage.
|
||||
$lockout = intval($data["lockout_secs"] ?? 60);
|
||||
if (!in_array($lockout, array_column(lockoutChoices(), "value"), true)) {
|
||||
$lockout = 60;
|
||||
}
|
||||
|
||||
$db->begin_transaction();
|
||||
try {
|
||||
@@ -386,10 +415,11 @@ function saveAutomation($data)
|
||||
|
||||
$stmt = $db->prepare("UPDATE automations SET name = ?, floor = ?, enabled = ?,
|
||||
window_from = ?, window_to = ?, weekdays = ?,
|
||||
on_vacation = ?, on_holiday = ?, force_once = ?
|
||||
on_vacation = ?, on_holiday = ?, force_once = ?,
|
||||
lockout_secs = ?
|
||||
WHERE id = ?");
|
||||
$stmt->bind_param("ssissiiiii", $name, $floor, $enabled, $windowFrom, $windowTo,
|
||||
$weekdays, $onVacation, $onHoliday, $forceOnce, $id);
|
||||
$stmt->bind_param("ssissiiiiii", $name, $floor, $enabled, $windowFrom, $windowTo,
|
||||
$weekdays, $onVacation, $onHoliday, $forceOnce, $lockout, $id);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
$db->query("DELETE FROM automation_conditions WHERE automation_id = " . $id);
|
||||
@@ -397,10 +427,10 @@ function saveAutomation($data)
|
||||
} else {
|
||||
$stmt = $db->prepare("INSERT INTO automations
|
||||
(name, floor, enabled, window_from, window_to, weekdays,
|
||||
on_vacation, on_holiday, force_once)
|
||||
VALUES (?,?,?,?,?,?,?,?,?)");
|
||||
$stmt->bind_param("ssissiiii", $name, $floor, $enabled, $windowFrom, $windowTo,
|
||||
$weekdays, $onVacation, $onHoliday, $forceOnce);
|
||||
on_vacation, on_holiday, force_once, lockout_secs)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?)");
|
||||
$stmt->bind_param("ssissiiiii", $name, $floor, $enabled, $windowFrom, $windowTo,
|
||||
$weekdays, $onVacation, $onHoliday, $forceOnce, $lockout);
|
||||
$stmt->execute();
|
||||
$id = $db->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
Reference in New Issue
Block a user