Hallo,
da ich nix für IPS gefunden habe was geht, habe ich (naja. okay. Claude) mal eben gebastelt.
Hier die Beta Version.
Bitte das Skript starten und dann erststellt es ein paar Childs wo man die Daten rein kloppen muss.
Falls Intersse daran ist, bitte Bescheid sagen, dann Poste ich Updates
<?php
$debug = true;
$parentID = $_IPS['SELF'];
// ==========================================
// Hilfsfunktionen
// ==========================================
function extractFloat($text) {
if (preg_match('/[+-]?\d+(?:[\.,]\d+)?/', $text, $m)) {
return (float)str_replace(',', '.', $m[0]);
}
return null;
}
function CreateChildVariable($ident, $name, $type, $profile = "", $icon = "", $position = 0) {
global $parentID;
$varID = @IPS_GetObjectIDByIdent($ident, $parentID);
if ($varID === false) {
$varID = IPS_CreateVariable($type);
IPS_SetName($varID, $name);
IPS_SetIdent($varID, $ident);
IPS_SetParent($varID, $parentID);
IPS_SetPosition($varID, $position);
if ($profile != "") IPS_SetVariableCustomProfile($varID, $profile);
if ($icon != "") IPS_SetIcon($varID, $icon);
}
return $varID;
}
// Wie oben, setzt aber EINMALIG beim Anlegen einen Default-Wert
function CreateChildVariableWithDefault($ident, $name, $type, $default, $profile = "", $icon = "", $position = 0) {
global $parentID;
$existing = @IPS_GetObjectIDByIdent($ident, $parentID);
$isNew = ($existing === false);
$varID = CreateChildVariable($ident, $name, $type, $profile, $icon, $position);
if ($isNew) {
SetValue($varID, $default);
}
return $varID;
}
// ==========================================
// Variablen anlegen
// ==========================================
$varUsernameID = CreateChildVariable("ConfigUsername", "1. Username / E-Mail", 3, "", "Mail", 10);
$varPasswordID = CreateChildVariable("ConfigPassword", "2. Passwort", 3, "~Password", "Key", 11);
$varWebAccessID = CreateChildVariable("ConfigWebAccessID", "3. Web Access ID (cid)", 3, "", "Network", 12);
$varOnlyActiveID = CreateChildVariable("AbrufNurBeiBetrieb", "4. Abruf nur bei Betrieb", 0, "~Switch", "Power", 13);
// Child mit der Objekt-ID der externen Pumpenstatus-Quelle, Default 22120
$varPumpSourceID = CreateChildVariableWithDefault("PumpStatusSourceID", "5. ID Pumpenstatus (Quelle)", 1, 22120, "", "Gauge", 14);
// Messwerte
$varPhID = CreateChildVariable("PoolPHWert", "Pool PH-Wert", 2, "~pH", "Drops", 20);
$varRedoxID = CreateChildVariable("Redoxwert", "Redoxwert", 2, "", "Electricity", 21);
$varTempID = CreateChildVariable("Pooltemperatur", "Pooltemperatur", 2, "~Temperature", "Temperature", 22);
// Alarme
$varPhAlarmID = CreateChildVariable("PoolPHAlarm", "Pool pH Alarm", 0, "~Alert", "Alert", 30);
$varRedoxAlarmID = CreateChildVariable("RedoxAlarm", "Redoxwert Alarm", 0, "~Alert", "Alert", 31);
$varTempAlarmID = CreateChildVariable("PooltempAlarm", "Pooltemperatur Warnung", 0, "~Alert", "Alert", 32);
// Kanister-Alarme (wieder da!)
$varPhCanisterEmptyID = CreateChildVariable("PhCanisterEmpty", "pH Kanister leer", 0, "~Alert", "Container", 40);
$varChlorCanisterEmptyID = CreateChildVariable("ChlorCanisterEmpty", "Chlor Kanister leer", 0, "~Alert", "Container", 41);
// ==========================================
// Timer
// ==========================================
$timerName = "Bayrol Abfrage-Timer";
$eventID = @IPS_GetEventIDByName($timerName, $parentID);
if ($eventID === false) {
$eventID = IPS_CreateEvent(1);
IPS_SetParent($eventID, $parentID);
IPS_SetName($eventID, $timerName);
IPS_SetEventCyclic($eventID, 0, 0, 0, 0, 1, 5);
IPS_SetEventActive($eventID, true);
}
// ==========================================
// Konfiguration laden
// ==========================================
$username = GetValue($varUsernameID);
$password = GetValue($varPasswordID);
$cid = trim(GetValue($varWebAccessID));
$onlyActive = GetValue($varOnlyActiveID);
// >>> PUMPENSTATUS: aus der externen Objekt-ID lesen <<<
$pumpSourceObjID = (int)GetValue($varPumpSourceID);
$filterPumpOn = false;
$pumpSourceOk = false;
if ($pumpSourceObjID > 0 && @IPS_ObjectExists($pumpSourceObjID)) {
$filterPumpOn = (bool)GetValue($pumpSourceObjID);
$pumpSourceOk = true;
}
if (empty($username) || empty($password) || empty($cid)) {
echo "Bitte Zugangsdaten in den Variablen unter dem Skript eintragen.\n";
return;
}
// ==========================================
// cURL-Abruf (läuft IMMER, damit im Debug-Log alle Werte erscheinen)
// ==========================================
$cookieFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'bayrol_cookie_' . preg_replace('/[^a-zA-Z0-9]/', '', $cid) . '.txt';
if ($debug) {
echo "=== DEBUG START ===\n";
echo "Windows Cookie-Pfad: $cookieFile\n";
echo "Pumpenstatus-Quelle: Objekt-ID $pumpSourceObjID" . ($pumpSourceOk ? "" : " (EXISTIERT NICHT -> Pumpe = AUS gewertet)") . "\n";
}
$ch = curl_init();
$commonOpts = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_COOKIEJAR => $cookieFile,
CURLOPT_COOKIEFILE => $cookieFile,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
CURLOPT_TIMEOUT => 20,
];
// --- SCHRITT 1: Login-Seite initial laden ---
$loginPageUrl = "https://www.bayrol-poolaccess.de/webview/m/login.php";
if ($debug) echo "1. Initialisiere Session auf: $loginPageUrl\n";
curl_setopt_array($ch, $commonOpts);
curl_setopt($ch, CURLOPT_URL, $loginPageUrl);
curl_exec($ch);
// --- SCHRITT 2: Login absenden ---
$loginTargetUrl = "https://www.bayrol-poolaccess.de/webview/m/login.php?r=reg";
if ($debug) echo "2. Sende POST-Login an: $loginTargetUrl\n";
curl_setopt_array($ch, $commonOpts);
curl_setopt($ch, CURLOPT_URL, $loginTargetUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'username' => $username, 'password' => $password, 'autologin' => 'None', 'login' => 'Anmelden'
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded',
'Referer: https://www.bayrol-poolaccess.de/webview/m/login.php'
]);
curl_exec($ch);
$loginHttpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$effectiveUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
if ($debug) {
echo "Login HTTP Code: $loginHttpCode\n";
echo "Effektive URL nach Login: $effectiveUrl\n";
}
// --- SCHRITT 3: getdata.php abrufen ---
$dataUrl = "https://www.bayrol-poolaccess.de/webview/getdata.php?cid=" . urlencode($cid);
if ($debug) echo "3. Rufe Pool-Daten ab von: $dataUrl\n";
curl_setopt_array($ch, $commonOpts);
curl_setopt($ch, CURLOPT_URL, $dataUrl);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Referer: https://www.bayrol-poolaccess.de/webview/m/plants.php']);
$dataResponse = curl_exec($ch);
$dataHttpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($debug) echo "Datenabruf HTTP Code: $dataHttpCode\n";
if (empty($dataResponse)) {
echo "CRITICAL ERROR: Keine HTML-Daten empfangen (Antwort ist komplett leer).\n";
return;
}
// --- VOLLSTÄNDIGER HTML-AUSZUG IM LOG (zum Analysieren) ---
if ($debug) {
echo "HTML-Antwort erhalten (Länge: " . strlen($dataResponse) . " Zeichen).\n";
echo "--- HTML AUSZUG START ---\n";
$cleanHtml = preg_replace('/\s+/', ' ', $dataResponse);
echo htmlspecialchars(substr($cleanHtml, 0, 1500)) . "...\n";
echo "--- HTML AUSZUG ENDE ---\n";
}
// ==========================================
// PARSEN
// ==========================================
$dom = new DOMDocument();
@$dom->loadHTML('<?xml encoding="UTF-8">' . $dataResponse);
$xpath = new DOMXPath($dom);
$phValue = $redoxValue = $tempValue = null;
$phCanisterEmpty = false;
$chlorCanisterEmpty = false;
// Werte über h1-Reihenfolge (pH, Redox, Temp)
$h1s = $xpath->query('//h1');
if ($h1s->length >= 3) {
$phValue = extractFloat($h1s->item(0)->nodeValue);
$redoxValue = extractFloat($h1s->item(1)->nodeValue);
$tempValue = extractFloat($h1s->item(2)->nodeValue);
}
// Fallback über Regex
if ($phValue === null && preg_match('/pH[^\d]*([\d\.,]+)/i', $dataResponse, $m)) $phValue = extractFloat($m[1]);
if ($redoxValue === null && preg_match('/mV[^\d]*([\d\.,]+)/i', $dataResponse, $m)) $redoxValue = extractFloat($m[1]);
if ($tempValue === null && preg_match('/°C[^\d]*([\d\.,]+)/i', $dataResponse, $m)) $tempValue = extractFloat($m[1]);
// Kanister-Status: aus den tab_box-Klassen der jeweiligen Box ableiten.
// Bayrol markiert leere Kanister mit den CSS-Klassen "stat_empty" bzw. "canister_empty".
$boxes = $xpath->query('//div[contains(@class, "tab_box")]');
foreach ($boxes as $box) {
$html = $dom->saveHTML($box);
$isEmptyBox = (stripos($html, 'canister_empty') !== false || stripos($html, 'stat_empty') !== false);
if (!$isEmptyBox) continue;
if (stripos($html, 'pH') !== false) $phCanisterEmpty = true;
if (stripos($html, 'Redox') !== false || stripos($html, 'mV') !== false) $chlorCanisterEmpty = true;
}
// Zusätzlicher Fallback über den Roh-HTML-Text
if (stripos($dataResponse, 'canister_empty') !== false || stripos($dataResponse, 'stat_empty') !== false) {
if ($debug) echo "HINWEIS: Kanister-Leer-Markierung im HTML gefunden.\n";
}
// Alarmgrenzen
$phAlarm = ($phValue !== null) ? ($phValue < 6.8 || $phValue > 7.6) : false;
$redoxAlarm = ($redoxValue !== null) ? ($redoxValue < 650.0) : false;
$tempAlarm = ($tempValue !== null) ? ($tempValue < 10.0 || $tempValue > 35.0) : false;
// ==========================================
// AUSGABE IM DEBUG-LOG (IMMER, komplett)
// ==========================================
echo "=== DATEN-ABRUF-BEREIT ===\n";
echo "Filterpumpe (aus Quelle-ID $pumpSourceObjID): " . ($filterPumpOn ? 'AN' : 'AUS') . "\n";
if ($phValue !== null) echo "pH-Wert: $phValue (Alarm: " . ($phAlarm ? 'JA' : 'NEIN') . " | Kanister leer: " . ($phCanisterEmpty ? 'JA' : 'NEIN') . ")\n";
if ($redoxValue !== null) echo "Redoxwert: $redoxValue mV (Alarm: " . ($redoxAlarm ? 'JA' : 'NEIN') . " | Kanister leer: " . ($chlorCanisterEmpty ? 'JA' : 'NEIN') . ")\n";
if ($tempValue !== null) echo "Pooltemperatur: $tempValue °C (Warnung: " . ($tempAlarm ? 'JA' : 'NEIN') . ")\n";
// ==========================================
// ABBRUCH-LOGIK: Pumpe aus -> NICHTS schreiben (Werte stehen oben im Log)
// ==========================================
if ($onlyActive && !$filterPumpOn) {
echo "=== ABBRUCH ===\n";
echo "Die Filterpumpe ist AUS. Alle Live-Werte wurden oben angezeigt, werden aber NICHT in die Variablen geschrieben.\n";
return;
}
// ==========================================
// SCHREIBEN (alles, wie am Anfang)
// ==========================================
echo "=== DATEN-UPDATE IN VARIABLE ===\n";
if ($phValue !== null) {
SetValue($varPhID, $phValue);
SetValue($varPhAlarmID, $phAlarm);
SetValue($varPhCanisterEmptyID, $phCanisterEmpty);
}
if ($redoxValue !== null) {
SetValue($varRedoxID, $redoxValue);
SetValue($varRedoxAlarmID, $redoxAlarm);
SetValue($varChlorCanisterEmptyID, $chlorCanisterEmpty);
}
if ($tempValue !== null) {
SetValue($varTempID, $tempValue);
SetValue($varTempAlarmID, $tempAlarm);
}
echo "Variablen erfolgreich in IP-Symcon aktualisiert.\n";