Files
Smart-Dashboard/ajax/watering.php
T
adminandClaude Opus 5 6e805678d4 Heizstab- und Bewaesserungsfenster im neuen Look, Bewaesserungszeilen enger
Beide Fenster lesen den Zustand live aus MQTT und uebernehmen jede Wahl
sofort (bedienfenster.js). submitFormAjax entfaellt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 21:26:16 +02:00

135 lines
5.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once("./phpMQTT.php");
require_once("../helper.php");
if ($_SERVER["REQUEST_METHOD"] === "POST") {
header("Content-Type: application/json; charset=utf-8");
if (!checkLogin()) {
http_response_code(401);
echo json_encode(["success" => false, "message" => "Nicht angemeldet."]);
exit;
}
$topic = $_POST["topic"] ?? "";
$payload = $_POST["payload"] ?? "";
$allowedTopics = [
"Gartenwasser/vorn/set",
"Gartenwasser/vorn/auto",
"Gartenwasser/hinten/set",
"Gartenwasser/hinten/auto"
];
if (!in_array($topic, $allowedTopics, true)) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Nicht erlaubtes MQTT-Topic."]);
exit;
}
if (str_ends_with($topic, "/set")) {
$command = json_decode($payload, true);
$validValve = is_array($command)
&& isset($command["valve"], $command["set"])
&& in_array((int) $command["valve"], [1, 6], true)
&& in_array($command["set"], ["open", "close"], true);
if ($validValve && $command["set"] === "open") {
$validValve = isset($command["timer"])
&& is_numeric($command["timer"])
&& (int) $command["timer"] >= 1
&& (int) $command["timer"] <= 120;
}
if (!$validValve) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Ungültiger Ventilbefehl."]);
exit;
}
$payload = json_encode($command, JSON_THROW_ON_ERROR);
} elseif (!in_array($payload, ["Hoch", "Vorn", "Trog", "Stop"], true)) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Ungültiger Automatikbefehl."]);
exit;
}
try {
$mqtt = new Bluerhinos\phpMQTT("localhost", 1883, "WateringWeb-" . bin2hex(random_bytes(4)));
if (!$mqtt->connect(true, null, "", "")) {
http_response_code(503);
echo json_encode(["success" => false, "message" => "MQTT-Broker nicht erreichbar."]);
exit;
}
$mqtt->publish($topic, $payload, 0, false);
$mqtt->close();
} catch (Throwable $error) {
http_response_code(503);
echo json_encode(["success" => false, "message" => "MQTT-Fehler: " . $error->getMessage()]);
exit;
}
echo json_encode(["success" => true, "topic" => $topic, "payload" => $payload]);
exit;
}
if (!checkLogin()) {
exit;
}
// Zonen des Fensters. Die Reihenfolge bestimmt die Reihenfolge der Karten;
// die Keys muessen zu wateringZones in js/solar/bewaesserungAnzeige.js passen,
// "bild" zu ZONENBILDER in js/solar/energiefluss.js. "dauern" sind die
// Schnellwahlen in Minuten, die erste ist die Vorgabe.
$zonen = [
["key" => "troughs", "label" => "Tröge", "bild" => "kuebel", "dauern" => [5, 10, 15, 30]],
["key" => "raisedBeds", "label" => "Beete", "bild" => "hochbeet", "dauern" => [30, 15, 45, 60]],
["key" => "frontGarden", "label" => "Vorn", "bild" => "garten", "dauern" => [30, 15, 45, 60]],
];
// Die Abläufe der Ventilsteuerung (Topic .../auto). Mehrere Einträge in
// "modi" starten bzw. stoppen gemeinsam.
$ablaeufe = [
["label" => "Tröge + Beete", "modi" => ["Gartenwasser/vorn" => "Trog", "Gartenwasser/hinten" => "Hoch"]],
["label" => "Tröge", "modi" => ["Gartenwasser/vorn" => "Trog"]],
["label" => "Beete", "modi" => ["Gartenwasser/hinten" => "Hoch"]],
["label" => "Vorn", "modi" => ["Gartenwasser/vorn" => "Vorn"]],
];
?>
<div class="lade wasser">
<div class="wasser-zonen">
<?php foreach ($zonen as $zone):
$dauern = $zone["dauern"];
sort($dauern); ?>
<div class="wasser-zone" data-zone="<?= $zone["key"] ?>" data-dauer="<?= $zone["dauern"][0] ?>">
<div class="wasser-kopf">
<span class="wasser-bild" data-bild="<?= $zone["bild"] ?>" aria-hidden="true"></span>
<div class="wasser-titel">
<b><?= htmlspecialchars($zone["label"]) ?></b>
<span data-w="zustand"></span>
</div>
<span class="lade-pille" data-w="pille"></span>
</div>
<div class="wasser-fuss">
<div class="lade-chips" role="group" aria-label="Dauer für <?= htmlspecialchars($zone["label"]) ?>">
<?php foreach ($dauern as $min): ?>
<button type="button" class="lade-chip" aria-pressed="false" data-min="<?= $min ?>"><?= $min ?>&#8201;min</button>
<?php endforeach; ?>
</div>
<button type="button" class="lade-start wasser-knopf" data-w="knopf"><span class="lade-punkt"></span><span data-w="knopfText">Gießen</span></button>
</div>
<div class="wasser-info" data-w="info"></div>
</div>
<?php endforeach; ?>
</div>
<div class="lade-abschnitt">
<h3>Abläufe</h3>
<div class="lade-chips wasser-ablaeufe">
<?php foreach ($ablaeufe as $ablauf): ?>
<button type="button" class="lade-chip" aria-pressed="false"
data-ablauf="<?= htmlspecialchars(json_encode($ablauf["modi"], JSON_UNESCAPED_SLASHES)) ?>"><?= htmlspecialchars($ablauf["label"]) ?></button>
<?php endforeach; ?>
</div>
<div class="lade-erklaerung">Ein Ablauf gießt die Zonen nacheinander antippen startet, nochmal antippen stoppt. Die Regenautomatik läuft davon unabhängig zum Sonnenaufgang.</div>
</div>
<div class="lade-meldung" data-w="meldung" aria-live="polite">Befehle gehen sofort an die Ventilsteuerung</div>
</div>