[SCRIPT] Stiebel Eltron ISG Gateway: HTML Seite auslesen

Stiebel Eltron Wärmepumpen liefern viele Werte über Modbus, aber einige zusätzliche Informationen sind nur im ISG-Webinterface sichtbar.

Mit diesem PHP-Skript lassen sich die Webdaten einfach auslesen:

  1. Rufe die ISG-Seite auf:
    http://<IP ISG-Gateway>/?s=1,1
    (Setze die IP entsprechend deiner Anlage ein.)

  2. Mit einem einfachen PHP-Check siehst du die verfügbaren Werte:

echo file_get_contents("http://192.168.xxx.xxx/?s=1,1");
  1. Vorgehensweise:
  • Wähle die gewünschten Daten aus
  • Lege hierfür eigene Variablen an
  • Passe das $items-Array des Skripts auf die IDs deiner Variablen an

Jetzt bekommst du alle im Webinterface sichtbaren Werte in deine Variablen geschrieben. Fertig!

So sollte es nachher aussehen:

Und dies ist das Skript

<?php
/**
 * Version: 1.0
 * Zweck: Liest Messwerte aus dem ISG-Webinterface (HTML-Tabellen) einer Wärmepumpe,
 *        entfernt Einheiten, konvertiert Zahlen (DE-Format) und schreibt sie typgerecht in IP‑Symcon-Variablen.
 */

declare(strict_types=1);

$items = [
    ['section' => 'PROZESSDATEN', 'caption' => 'AUSSENTEMPERATUR', 'id' => 59289, 'suffix' => '°C', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'PROZESSDATEN', 'caption' => 'ISTDREHZAHL VERDICHTER', 'id' => 46905, 'suffix' => 'Hz', 'type' => VARIABLETYPE_INTEGER],
    ['section' => 'PROZESSDATEN', 'caption' => 'LÜFTERLEISTUNG RELATIV', 'id' => 25050, 'suffix' => '%', 'type' => VARIABLETYPE_INTEGER],
    ['section' => 'PROZESSDATEN', 'caption' => 'AUFNAHMELEISTUNG INVERTER', 'id' => 27660, 'suffix' => 'kW', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'LAUFZEIT', 'caption' => 'VD HEIZEN', 'id' => 50426, 'suffix' => 'h', 'type' => VARIABLETYPE_INTEGER],
    ['section' => 'LAUFZEIT', 'caption' => 'VD WARMWASSER', 'id' => 26540, 'suffix' => 'h', 'type' => VARIABLETYPE_INTEGER],
    ['section' => 'LAUFZEIT', 'caption' => 'VD ABTAUEN', 'id' => 33131, 'suffix' => 'h', 'type' => VARIABLETYPE_INTEGER],
    ['section' => 'LAUFZEIT', 'caption' => 'NHZ 1/2', 'id' => 27244, 'suffix' => 'h', 'type' => VARIABLETYPE_INTEGER],
    ['section' => 'LAUFZEIT', 'caption' => 'ZEIT ABTAUEN', 'id' => 36364, 'suffix' => 'min', 'type' => VARIABLETYPE_INTEGER],
    ['section' => 'LAUFZEIT', 'caption' => 'STARTS ABTAUEN', 'id' => 48484, 'suffix' => '', 'type' => VARIABLETYPE_INTEGER],
    ['section' => 'LEISTUNGSAUFNAHME', 'caption' => 'VD HEIZEN TAG', 'id' => 21834, 'suffix' => 'KWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'LEISTUNGSAUFNAHME', 'caption' => 'VD HEIZEN SUMME', 'id' => 36488, 'suffix' => 'MWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'LEISTUNGSAUFNAHME', 'caption' => 'VD WARMWASSER TAG', 'id' => 48352, 'suffix' => 'KWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'LEISTUNGSAUFNAHME', 'caption' => 'VD WARMWASSER SUMME', 'id' => 31175, 'suffix' => 'MWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'WÄRMEMENGE', 'caption' => 'VD HEIZEN TAG', 'id' => 27081, 'suffix' => 'KWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'WÄRMEMENGE', 'caption' => 'VD HEIZEN SUMME', 'id' => 40762, 'suffix' => 'MWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'WÄRMEMENGE', 'caption' => 'VD WARMWASSER TAG', 'id' => 51812, 'suffix' => 'KWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'WÄRMEMENGE', 'caption' => 'VD WARMWASSER SUMME', 'id' => 10368, 'suffix' => 'MWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'WÄRMEMENGE', 'caption' => 'NHZ HEIZEN SUMME', 'id' => 29541, 'suffix' => 'MWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'WÄRMEMENGE', 'caption' => 'NHZ WARMWASSER SUMME', 'id' => 43127, 'suffix' => 'MWh', 'type' => VARIABLETYPE_FLOAT],
    ['section' => 'STARTS', 'caption' => 'VERDICHTER', 'id' => 35229, 'suffix' => '', 'type' => VARIABLETYPE_INTEGER],
];


// Konfiguration
$isgIp = '192.168.10.24';


//****** ab hier nichts mehr ändern *****

$url   = sprintf('http://%s/?s=1,1', $isgIp);

// Timeout/Fehlerbehandlung für HTTP
$ctx  = stream_context_create(['http' => ['timeout' => 10]]);
$html = file_get_contents($url, false, $ctx);

if ($html === false) {
    throw new RuntimeException(sprintf('Fehler beim Lesen von %s', $url));
}

// Verarbeitung
foreach ($items as $item) {
    $raw = extractValueFromSection($html, (string)$item['section'], (string)$item['caption']);
    $value = parseValue($raw, (string)$item['suffix']);
    setValueByType((int)$item['id'], (int)$item['type'], $value);
}


//-------------------------------------------------------------------------------------------
function extractValueFromSection(string $html, string $sectionTitle, string $key): string
{
    // Finde die Tabelle mit dem Sektions-Titel in <th>
    // Pattern: <th ...>SECTION_TITLE</th> ... bis zur nächsten <th> oder </table>
    $section_pattern =
        '/<th[^>]*class="[^"]*round-top[^"]*"[^>]*>\s*' . preg_quote($sectionTitle, '/') . '\s*<\/th>.*?(<\/table>|<th[^>]*class="[^"]*round-top)/s';

    if (preg_match($section_pattern, $html, $section_matches)) {
        $section_html = $section_matches[0];

        // Innerhalb der Sektion nach dem Key suchen (exakter Match)
        $pattern =
            '/<td[^>]*class="[^"]*key[^"]*"[^>]*>\s*' . preg_quote($key, '/') . '\s*<\/td>\s*<td[^>]*class="[^"]*value[^"]*"[^>]*>([^<]+)<\/td>/s';

        if (preg_match($pattern, $section_html, $matches)) {
            return trim($matches[1]);
        }
    }
    throw new RuntimeException('Kein Treffer für Schlüssel: ' . $key);
}

function parseValue(string $raw, string $suffix): string
{
    // Entfernt das erwartete Suffix (falls vorhanden) und trimmt
    $value = trim($raw);
    if ($suffix !== '' && str_ends_with($value, $suffix)) {
        $value = substr($value, 0, -strlen($suffix));
    } else {
        // Fallback: Hartes Entfernen des Suffix-Strings, falls eingebettet
        $value = str_replace($suffix, '', $value);
    }
    return trim($value);
}

function setValueByType(int $id, int $type, string $stringValue): void
{
    if ($type === VARIABLETYPE_FLOAT) {
        $float = toFloatDe($stringValue);
        if ($float === null) {
            // Ungültiger Float → nichts schreiben
            return;
        }
        SetValueFloat($id, $float);
        return;
    }
    // Integer
    SetValueInteger($id, (int)$stringValue);
}

function toFloatDe(string $s): ?float
{
    $s = trim($s);
    // Tausenderpunkte entfernen, Dezimalkomma zu Punkt
    $norm = str_replace(['.', ','], ['', '.'], preg_replace('/\s/u', '', $s));
    if (!is_numeric($norm)) {
        return null; // ungültig
    }
    return (float)$norm;
}