hydropmeter mit IP‑Symcon verbinden
Für das Einbinden deines hydropmeter in IP-Symcon benötigst du folgende Dinge:
- einen Account in der hydrop App (verfügbar für Android und iOS)
- den Namen, den du deinem hydropmeter in der App gegeben hast
- deinen persönlichen API-Key für die hydrop REST-API
Den API-Key findest du in der hydrop App unter Einstellungen -> Konto -> API-Key. Bitte speichere den Key direkt ab, da er nur einmal angezeigt wird.
Wenn du alle Informationen bereit hast, kann es losgehen. Die Abfrage der Daten in IP-Symcon erfolgt mit einem PHP-Skript. Das Skript hierfür findest du im Codeblock.
Öffne zunächst den Objektbaum in der Verwaltungskonsole deiner IP-Symcon-Instanz und klicke unten rechts auf das „+“-Symbol, um ein neues Objekt zu erstellen. Um das PHP-Skript dem Objektbaum hinzuzufügen, wähle Automation und dann PHP-Skript aus. Lege den Namen und Speicherort für das neue Skript fest und bestätige die Erstellung. Es öffnet sich der Skripteditor. Eventuell sind bereits einige Zeilen im neuen Skript vorhanden. Diese werden nicht weiter benötigt und sollten entfernt oder überschrieben werden. Kopiere die Codevorlage und füge sie 1:1 im Skripteditor ein.
Ersetze die Platzhalter im Konfigurations-Abschnitt für den API-Key, den Gerätenamen und gegebenenfalls die Zeitzone.
Die Variablen für den Zählerstand, den Zeitstempel der letzten Messung und den Tagesverbrauch werden vom Skript automatisch angelegt und im Objektbaum unter dem PHP-Skript eingruppiert. Möchtest du deine eigenen Variablen verwenden, kannst du im Konfigurations-Abschnitt die Variablen-IDs der gewünschten Variablen einfügen. Dann verwendet das Skript diese und wird keine eigenen erstellen.
Nun kann das Skript abgespeichert und ausgeführt werden. Klicke dazu auf den Button oben rechts in der Menüleiste des Skript-Editors.
Im Objektbaum sollten nun die entsprechenden Variablen mit den Werten von deinem hydropmeter befüllt werden. Das Skript erzeugt automatisch einen Timer, der den Zählerstand alle 5 Minuten aktualisiert. Ob die Erstellung des Timers erfolgreich war siehst du, wenn du im Objektbaum den Bereich unterhalb deines erstellten PHP-Skripts ausklappst. Dort sollte ein Timer-Objekt vorhanden sein.
Achtung: Bitte gehe sorgsam mit deinem API-Key um und lasse ihn nicht in falsche Hände geraten.
<?php
/**
* hydropmeter-Integration für IP-Symcon
*
* Ruft alle 5 Minuten den aktuellen Wasserzählerstand von der hydrop REST-API ab,
* berechnet den Tagesverbrauch und aktiviert die Archivierung für Diagramme.
*
* @author hydrop systems GmbH
* @version 1.1.0
* @date 2025-10-10
* @license MIT
*
* @requires IP-Symcon 5.x+
* @requires Internetzugang zu https://api.hydrop-systems.com
* @requires Gültiger hydrop API-Schlüssel und Gerätename
*/
// ╔══════════════════════════════════════════════════════════════╗
// ║ KONFIGURATION ║
// ╠══════════════════════════════════════════════════════════════╣
// ║ API-Zugangsdaten und optionale Variablen-IDs konfigurieren ║
// ╚══════════════════════════════════════════════════════════════╝
$apiKey = '<<HIER API-KEY EINFÜGEN>>';
$device = '<<HIER GERÄTENAME EINFÜGEN>>'; // Gerätename aus der hydrop App
$timezone = 'Europe/Berlin';
// Optionale Variablen-IDs (0 = automatisch anlegen; Variablen-ID = vorhandene Variable verwenden)
$varMeter = 0; // Float: Zählerstand - bei 0 wird automatisch "Zählerstand" angelegt (Archivierung aktiviert)
$varTime = 0; // String: Zeitstempel der letzten Messung - bei 0 wird automatisch "Letzte Messung" angelegt
$varDaily = 0; // Float: Tagesverbrauch - bei 0 wird automatisch "Tagesverbrauch" angelegt (Archivierung aktiviert)
// ╔══════════════════════════════════════════════════════════════╗
// ║ ENDE KONFIGURATION ║
// ╚══════════════════════════════════════════════════════════════╝
date_default_timezone_set($timezone);
// Benutzerdefiniertes Profil für Kubikmeter erstellen (falls noch nicht vorhanden)
$meterValueProfile = 'Water.CubicMeter';
if (!IPS_VariableProfileExists($meterValueProfile)) {
IPS_CreateVariableProfile($meterValueProfile, 2); // 2 = Float
IPS_SetVariableProfileText($meterValueProfile, '', ' m³');
IPS_SetVariableProfileDigits($meterValueProfile, 4); // 4 Nachkommastellen
IPS_SetVariableProfileIcon($meterValueProfile, 'meter-droplet');
IPS_LogMessage('hydropmeter', 'Variablenprofil "Water.CubicMeter" erstellt');
}
// Zählerstands-Variable prüfen und ggf. erstellen
if ($varMeter === 0) {
$varMeter = @IPS_GetObjectIDByIdent('MeterValue', $_IPS['SELF']);
if ($varMeter === false) {
$varMeter = IPS_CreateVariable(2); // Float
IPS_SetName($varMeter, 'Zählerstand');
IPS_SetIdent($varMeter, 'MeterValue');
IPS_SetParent($varMeter, $_IPS['SELF']);
IPS_SetVariableCustomProfile($varMeter, $meterValueProfile);
IPS_LogMessage('hydropmeter', 'Variable "Zählerstand" erstellt (ID: ' . $varMeter . ')');
}
} else {
if (!IPS_VariableExists($varMeter)) {
IPS_LogMessage('hydropmeter', 'FEHLER: Zählerstands-Variable (ID ' . $varMeter . ') existiert nicht');
return;
}
}
// Zeitstempel-Variable prüfen und ggf. erstellen
if ($varTime === 0) {
$varTime = @IPS_GetObjectIDByIdent('LastUpdate', $_IPS['SELF']);
if ($varTime === false) {
$varTime = IPS_CreateVariable(3); // String
IPS_SetName($varTime, 'Letzte Messung');
IPS_SetIdent($varTime, 'LastUpdate');
IPS_SetParent($varTime, $_IPS['SELF']);
IPS_LogMessage('hydropmeter', 'Variable "Letzte Messung" erstellt (ID: ' . $varTime . ')');
}
} else {
if (!IPS_VariableExists($varTime)) {
IPS_LogMessage('hydropmeter', 'FEHLER: Zeitstempel-Variable (ID ' . $varTime . ') existiert nicht');
return;
}
}
// Variable für Tagesverbrauch anlegen
if ($varDaily === 0) {
$varDaily = @IPS_GetObjectIDByIdent('DailyUsage', $_IPS['SELF']);
if ($varDaily === false) {
$varDaily = IPS_CreateVariable(2);
IPS_SetName($varDaily, 'Tagesverbrauch');
IPS_SetIdent($varDaily, 'DailyUsage');
IPS_SetParent($varDaily, $_IPS['SELF']);
IPS_SetVariableCustomProfile($varDaily, "~Water");
IPS_LogMessage('hydropmeter', 'Variable "Tagesverbrauch" erstellt (ID: ' . $varDaily . ')');
}
} else {
if (!IPS_VariableExists($varDaily)) {
IPS_LogMessage('hydropmeter', 'FEHLER: Tagesverbrauch-Variable (ID ' . $varDaily . ') existiert nicht');
return;
}
}
// Versteckte Hilfsvariable für den Tagesstartwert zur Berechnung des Tagesverbrauchs
$varDayStart = @IPS_GetObjectIDByIdent('DayStartValue', $_IPS['SELF']);
if ($varDayStart === false) {
$varDayStart = IPS_CreateVariable(2); // Float
IPS_SetName($varDayStart, 'Tagesstartwert (intern)');
IPS_SetIdent($varDayStart, 'DayStartValue');
IPS_SetParent($varDayStart, $_IPS['SELF']);
IPS_SetVariableCustomProfile($varDayStart, $meterValueProfile);
IPS_SetHidden($varDayStart, true);
SetValue($varDayStart, 0.0);
}
// Versteckte Hilfsvariable für den Datumsvergleich zur Berechnung des Tagesverbrauchs
$varLastDate = @IPS_GetObjectIDByIdent('LastProcessedDate', $_IPS['SELF']);
if ($varLastDate === false) {
$varLastDate = IPS_CreateVariable(3); // String für Datum (Y-m-d)
IPS_SetName($varLastDate, 'Datum der letzten Abfrage (intern)');
IPS_SetIdent($varLastDate, 'LastProcessedDate');
IPS_SetParent($varLastDate, $_IPS['SELF']);
IPS_SetHidden($varLastDate, true);
}
// Archivierung für Zählerstand und Tagesverbrauch aktivieren
$archiveList = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}');
if (!empty($archiveList)) {
try {
AC_SetLoggingStatus($archiveList[0], $varMeter, true);
AC_SetLoggingStatus($archiveList[0], $varDaily, true);
IPS_ApplyChanges($archiveList[0]);
IPS_LogMessage('hydropmeter', 'Archivierung für Zählerstand und Tagesverbrauch aktiviert');
} catch (Exception $e) {
IPS_LogMessage('hydropmeter', 'Archivierungsfehler: ' . $e->getMessage());
}
}
// Automatischen Aktualisierungs-Timer erstellen (alle 5 Minuten)
$eventName = "hydropmeter_auto_update_" . $_IPS['SELF'];
$eventID = @IPS_GetObjectIDByIdent($eventName, $_IPS['SELF']);
if ($eventID === false) {
$eventID = IPS_CreateEvent(1);
IPS_SetParent($eventID, $_IPS['SELF']);
IPS_SetIdent($eventID, $eventName);
IPS_SetName($eventID, "hydropmeter Auto-Update");
IPS_SetEventCyclic($eventID, 0, 0, 0, 0, 2, 5);
IPS_SetEventScript($eventID, 'IPS_RunScriptEx(' . $_IPS['SELF'] . ', []);');
IPS_SetEventActive($eventID, true);
IPS_LogMessage('hydropmeter', 'Timer erstellt (alle 5 Minuten)');
}
// Daten von der hydrop REST-API abrufen
$url = sprintf('https://api.hydrop-systems.com/sensors/ID/%s/newest', $device);
$opts = [
'http' => [
'method' => 'GET',
'header' => sprintf("apikey: %s\r\nAccept: application/json\r\n", $apiKey),
'timeout' => 15,
'ignore_errors' => true,
],
];
$context = stream_context_create($opts);
$result = @file_get_contents($url, false, $context);
if ($result === false) {
$error = error_get_last();
IPS_LogMessage('hydropmeter', 'API-Anfrage fehlgeschlagen: ' . ($error ? $error['message'] : 'Unbekannter Fehler'));
if (isset($http_response_header)) {
IPS_LogMessage('hydropmeter', 'HTTP-Antwort: ' . $http_response_header[0]);
}
return;
}
$data = json_decode($result, true);
if ($data === null) {
IPS_LogMessage('hydropmeter', 'JSON-Dekodierungsfehler: ' . json_last_error_msg());
IPS_LogMessage('hydropmeter', 'Klartext der Antwort: ' . substr($result, 0, 200));
return;
}
// Zählerstand verarbeiten
if (!isset($data['sensors'][0]['records'][0])) {
IPS_LogMessage('hydropmeter', 'Keine gültigen Datensätze in API-Antwort gefunden');
IPS_LogMessage('hydropmeter', 'Antwortstruktur: ' . print_r($data, true));
return;
}
$record = $data['sensors'][0]['records'][0];
$meterValue = (float) $record['meterValue'];
$currentTimestamp = (int) $record['timestamp'];
// Zähler- und Zeitstempel-Variablen aktualisieren
try {
SetValue($varMeter, $meterValue);
SetValue($varTime, date('d.m.Y H:i:s', $currentTimestamp)); // Deutsches Format für Anzeige
} catch (Exception $e) {
IPS_LogMessage('hydropmeter', 'Fehler beim Setzen der Variablen: ' . $e->getMessage());
return;
}
// Tagesverbrauch berechnen
$currentDate = date('Y-m-d', $currentTimestamp);
$lastProcessedDate = GetValue($varLastDate);
// Prüfen ob ein neuer Tag begonnen hat
$dayChanged = ($lastProcessedDate !== $currentDate && $lastProcessedDate !== '');
if ($dayChanged) {
// Tagesverbrauch des VORHERIGEN Tages berechnen
$dayStartValue = GetValue($varDayStart);
$currentMeterValue = GetValue($varMeter);
if ($dayStartValue > 0) {
$dailyUsage = round(max(0, ($currentMeterValue - $dayStartValue) * 1000.0), 1);
try {
SetValue($varDaily, $dailyUsage);
IPS_LogMessage('hydropmeter', "Tagesverbrauch für $lastProcessedDate: $dailyUsage Liter");
} catch (Exception $e) {
IPS_LogMessage('hydropmeter', 'Fehler beim Setzen des Tagesverbrauchs: ' . $e->getMessage());
}
}
// Neuen Tagesstartwert setzen
SetValue($varDayStart, $meterValue);
IPS_LogMessage('hydropmeter', "Neuer Tag erkannt: Startwert = $meterValue m³");
}
// Interne Hilfsvariablen für den nächsten Vergleich aktualisieren
try {
SetValue($varLastDate, $currentDate);
// Beim ersten Ausführen: Tagesstartwert initialisieren, wenn noch nicht gesetzt
$dayStartValue = GetValue($varDayStart);
if ($dayStartValue === 0.0) {
SetValue($varDayStart, $meterValue);
IPS_LogMessage('hydropmeter', "Tagesstartwert initialisiert: $meterValue m³");
}
} catch (Exception $e) {
IPS_LogMessage('hydropmeter', 'Fehler beim Speichern der aktuellen Werte: ' . $e->getMessage());
}
IPS_LogMessage('hydropmeter', "Aktualisierung erfolgreich: $meterValue m³, " . date('d.m.Y H:i:s', $currentTimestamp));