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 Modals. Die Reihenfolge bestimmt die Reihenfolge der Karten, die // Keys muessen zu wateringZones in js/solar/solarMQTT.js passen. $zonen = [ ["key" => "troughs", "label" => "Tröge", "minuten" => 5], ["key" => "raisedBeds", "label" => "Beete", "minuten" => 30], ["key" => "frontGarden", "label" => "Vorn", "minuten" => 30], ]; // Was die Automatik je Zone vorhat, fuellt solarMQTT.js aus dem RainStatus. $planZeilen = ""; foreach ($zonen as $zone) { $planZeilen .= "