Module Watchdog LCN – zentrale Überwachung von LCN-Modulen

Ich habe für meine eigene Installation ein kleines IP-Symcon-Modul entwickelt, das inzwischen auch im Module Store verfügbar ist: Module Watchdog LCN.

Das Modul überwacht zentral beliebig viele LCN-Module. Solange ein Modul regulär Telegramme sendet, werden diese als Lebenszeichen verwendet. Bleibt ein Modul für eine definierte Zeit still, wird es aktiv abgefragt. Mehrere notwendige Abfragen werden dabei mit einem konfigurierbaren Mindestabstand nacheinander ausgeführt, damit keine Command-Bursts auf dem LCN-Bus entstehen.

Der Status aller überwachten Module (Alive, Offline, Unknown, Disabled) wird in einer zentralen JSON-Variable bereitgestellt und kann damit einfach über Events oder eigene Scripts ausgewertet werden.

Ich verwende das nicht nur zur eigentlichen Modulüberwachung. Da ich weiss, welche LCN-Module hinter welcher Sicherung hängen, kann ich beispielsweise auch erkennen, dass wahrscheinlich eine Sicherung ausgelöst hat, wenn die entsprechenden Module mehr oder weniger gleichzeitig offline gehen.

Das Modul ist bewusst auf die technische Überwachung beschränkt; Alarmierung, Visualisierung oder weitere Auswertung kann man darauf aufbauend nach eigenen Bedürfnissen realisieren.

Das Modul findet Ihr im IP-Symcon Module Store unter Module Watchdog LCN.

Für Fragen, Anregungen oder Rückmeldungen stehe ich gerne zur Verfügung.

Viele Grüsse, Ueli

3 „Gefällt mir“

Hallo Ueli,

beim Installieren des Moduls kommt folgende Fehlermeldung.

image

Hallo Meike.
Kannst Du mir bitte sagen, auf welcher Plattform bei Dir IP-Symcon läuft? Ich tippen auf eine 32-Bit Umgebung, möchte mich aber vergewissern.

Ja, Symcon läuft auf einem 32Bit-System unter Docker

Ist das ein NAS, welches nur 32 Bit kann, oder ist es ein Pi, auf dem du aktuell noch nicht auf 64 Bit gewechselt hast? :slight_smile:

paresy

Docker läuft auf einem PI 32Bit

Ich habe es auf einem Pi4 64bit am laufen.
Ich würde in deiner Stelle auch auf ein 64 bit System gehen.

Thomas

Läuft bei mir auch auf PI4 64bit, ich würde mir noch eine Variable mit der Anzahl der gestörten Module wünschen, dann wäre eine Auswertung schneller/einfacher möglich.

Meine Empfehlung ist auf auf 64 Bit zu migrieren. 32 Bit wird vermutlich bald keine Updates bekommen.

paresy

Ja, der Fall ist klar. Ich verwende intern microtime() und rechne den Unix-Timestamp auf Millisekunden um. Dieser Wert überschreitet PHP_INT_MAX auf einer 32-Bit-Plattform.

Ich werde das Modul entsprechend anpassen. Absolute Zeitpunkte werden künftig nur noch in Unix-Sekunden gespeichert. Lediglich für die kurzen Intervalle zwischen den LCN-Commands bleibt die Millisekundenauflösung erhalten.

Danke für die Fehlermeldung! Ich denke, der Patch sollte noch heute im Test-Kanal verfügbar sein.

@ralf Falls Du damit die vom Watchdog als Offline erkannten LCN-Module meinst: Der Status aller überwachten Module steht bereits in der Statusvariable als JSON zur Verfügung und kann darüber ausgewertet werden. So mache ich es auch: Ein Script wertet das JSON aus und wird über ein Ereignis aufgerufen, das auf Änderungen der Statusvariable reagiert.

Falls Du Dir zusätzlich eine einfache Integer-Variable mit der Anzahl der aktuell ausgefallenen LCN-Module wünschst, sag kurz Bescheid. Das wäre technisch problemlos machbar.

Ich meinte eine Integer Variable, dann kann ein Profil drauf und sie lässt sich direkt in IPSview nutzen ohne weitere Scripte.

Ansonsten funktioniert das Modul gut, ich habe ein altes UPP das sich immer mal wieder aufhängt.

Ah, jetzt verstehe ich besser, was Du meinst. Nur damit ich die gewünschte Funktion richtig verstehe: Du möchtest zusätzlich zur JSON-Statusvariable eine Integer-Variable, die einfach die Anzahl der aktuell als Offline erkannten LCN-Module enthält? Also 0 = kein Modul offline, 1 = ein Modul offline usw.? Oder verstehe ich Dich falsch?

Das liesse sich problemlos ergänzen.

Korrekt, einfach die Anzahl der gestörten, dann geht 0=grün und größer 0=rot und die Zahl zur Darstellung.

Wäre es nicht besser, 0 (grün)=Alle ok, 1 (gelb)=Mindestens ein Modul ist unknown, aber keines ist offline, 2 (rot)=Mindestens ein Modul ist offline?

1 „Gefällt mir“

Das Profil kann sich ja jeder selber setzen, wenn es die Variable gibt :innocent:.

Ja, klar. Ich wollte nur verstehen, was Du mit der Variable genau erreichen möchtest.

Ich würde sie im Moment trotzdem eher nicht zusätzlich ins Modul aufnehmen. Die Information ist bereits vollständig in der Statusvariable vorhanden und die Anzahl der Offline-Module lässt sich mit einem kleinen Script und einem Event sehr einfach daraus ableiten.

Ich versuche ausserdem, bei meinen Modulen mit zusätzlichen Variablen eher sparsam umzugehen. Je nach IP-Symcon-Lizenz und Anzahl der Instanzen spielt die Anzahl der angelegten Variablen durchaus eine Rolle. Das war auch einer der Hauptgründe für die komplette Überarbeitung des Watchdogs: Die frühere Version benötigte für jedes überwachte LCN-Modul eine eigene Integer-Variable mit dem Status Online, Unknown oder Offline. Die neue Version fasst den Zustand aller überwachten Module bewusst in einer einzigen Statusvariable zusammen.

Deshalb möchte ich nicht wieder zusätzliche Variablen für einzelne Auswertungen einführen, wenn sich die Information bereits einfach aus den vorhandenen Daten ableiten lässt.

Falls sich zeigt, dass diese zusätzliche Variable von mehreren Anwendern gewünscht wird, werden wir das natürlich nochmals anschauen.

Hier ein einfaches Script, das die Variable pflegen würde. Aufgerufen bei Änderung der JSON-Status-Variablen, einfach noch die entsprechende Integer-Status-Variable erstellen und im Code eintragen:

$status = json_decode($_IPS['VALUE], true);

$offline = count(array_filter(
$status,
static fn($value) => $value === 'Offline'
));

SetValue(67890, $offline);

Der korrigierte Build 7 wurde inzwischen auch erfolgreich auf der 32-Bit-Installation von @meike0_0 getestet.
Ich habe die neue Version gerade für den Module Store eingereicht. Sie wartet jetzt auf den Review durch Symcon.

Nochmals danke für die Fehlermeldung und fürs Testen

Da ist ein kleiner Fehler drin.

Ich habe mal etwas geschnitzt, was drei Variablen mit Profil anlegt. Fehler, Unknown und eine Tabelle als Übersicht mit Fehler und Unkown.

<?php

// =============================================================
// Profil anlegen (Grün bei 0, Rot bei >0, tatsächlicher Wert anzeigen)
// =============================================================

$profileName = "Module.Status";

if (!IPS_VariableProfileExists($profileName)) {
    IPS_CreateVariableProfile($profileName, 1); // Integer
    IPS_SetVariableProfileValues($profileName, 0, 50, 1); // Max 50 Fehler, mehr haben hoffentlich keinen Fehler

    IPS_SetVariableProfileIcon($profileName, "Warning");

    // 0 = Grün
    IPS_SetVariableProfileAssociation($profileName, 0, "0", "", 0x00FF00);

    // 1–50 = Rot
    for ($i = 1; $i <= 50; $i++) {
        IPS_SetVariableProfileAssociation($profileName, $i, (string)$i, "", 0xFF0000);
    }
}


// =============================================================
// Variablen automatisch anlegen
// =============================================================

$parent = $_IPS['SELF']; // Script als Parent

$vErrors  = CreateVariableByIdent($parent, "ModuleErrors",  "Module Fehler (Offline)", 1, 10, $profileName);
$vUnknown = CreateVariableByIdent($parent, "ModuleUnknown", "Module Unknown",          1, 20, $profileName);
$vHtml    = CreateVariableByIdent($parent, "ModuleStatusHtml", "Module Status Tabelle", 3, 30, "~HTMLBox");


// =============================================================
// JSON laden
// =============================================================

$status = json_decode(GetValue(36740), true);

// Ungültiges oder leeres JSON → 999 setzen
if (!is_array($status)) {
    SetValue($vErrors, 999);
    SetValue($vUnknown, 999);
    SetValue($vHtml, "<p>Keine gültigen Daten</p>");
    return;
}


// =============================================================
// Fehler getrennt zählen
// =============================================================

// Offline
$errors = count(array_filter(
    $status,
    static fn($value) => $value === 'Offline'
));

// Unknown
$unknown = count(array_filter(
    $status,
    static fn($value) => $value === 'Unknown'
));

SetValue($vErrors, $errors);
SetValue($vUnknown, $unknown);


// =============================================================
// HTML-Tabelle erzeugen (nur Offline + Unknown)
// =============================================================

$html = '<table style="width:100%; border-collapse:collapse;" border="1" cellpadding="4" cellspacing="0">';
$html .= '<tr><th>ID</th><th>Name</th><th>Status</th></tr>';

foreach ($status as $id => $value) {

    if ($value !== 'Alive') {
        $name = IPS_GetName((int)$id);

        $html .= sprintf(
            '<tr><td>%s</td><td>%s</td><td>%s</td></tr>',
            $id,
            htmlspecialchars($name),
            $value
        );
    }
}

$html .= '</table>';

SetValue($vHtml, $html);


// =============================================================
// Hilfsfunktion
// =============================================================

function CreateVariableByIdent($parent, $ident, $name, $type, $position, $profile = "") {
    $vid = @IPS_GetObjectIDByIdent($ident, $parent);
    if ($vid === false) {
        $vid = IPS_CreateVariable($type);
        IPS_SetParent($vid, $parent);
        IPS_SetName($vid, $name);
        IPS_SetIdent($vid, $ident); 
        IPS_SetPosition($vid, $position);
    }
    if ($profile != "" && IPS_VariableProfileExists($profile)) {
        IPS_SetVariableCustomProfile($vid, $profile);
    }
    return $vid;
}

Hallo Ralf

Sieht gut aus, die Darstellung.

Aber was meinst Du mit „Da ist ein kleiner Fehler drin“? Einen Fehler in meinem Beispielscript oder hast Du einen Fehler im Module Watchdog gefunden?

Ich bräuchte noch ein bisschen mehr Informationen.