Zigbee Überwachung

Moin,
Zigbee ist hier ja sehr beliebt weil es viele Sensoren/Aktoren zu einem kleinen Preis gibt. Damit es immer wie gewünscht arbeitet muss es aber auch überwacht werden. Bei batteriebetriebenen Sensoren bietet sich die Überwachung mit dem Batterie-/Profil-Monitor an. Leider sind die meisten Batterieangaben der Sensoren eher Wunschdenken als Realität. In diesen Fällen kann ein Watchdog auf Aktualisierung (NICHT Änderung) der Verbindungsqualität helfen. Jetzt ist aber die Frage welche Zeit muss man einstellen? Da gibt es keine allgemeingültige Antwort. Die Sensoren antworten mal jede Stunde mal aber auch nur alle X Tage.

Um eine Hilfe bei der Wahl der Zeiten zu bieten habe ich mal wieder ein kleines Script geschrieben das in einer Tabelle die maximale Zeitdifferenz zwischen 2 Meldungen ermittelt und in einer netten Tabelle darstellt. Geschrieben habe ich es für Z2M mit Kais Modul und aktiviertem last_seen in Z2M. Es kann aber vermutlich leicht für andere Module/Zwecke angepasst werden.

Wie arbeitet es? Beim ersten Start werden die Variablen „Devices“ und „Tabelle“ sowie ein Scripttimer eingerichtet. Es wird ein Feld erstellt mit allen Geräten die „last_seen“ haben. In diesem Feld stehen ID, Parentname und Name sowie der jetzige „last_seen“ Wert und die maximale Differenzen zwischen den „last_seen“ Werten. Dieses Feld wird json_encoded in Devices gespeichert. Bei jedem Timerdurchlauf wird geschaut ob sich „last_seen“ geändert hat und wenn ja wird ermittelt ob die Differenz der letzten 2 Werte größer als das jetzige Maximum ist und das wird im Feld „Max“ gespeichert. Am Ende wird die Tabelle aktualisiert.

Hier das Script:

<?php
$DevicesID = @IPS_GetVariableIDByName("Devices", $_IPS['SELF']);
if ($DevicesID == false){
    $DevicesID = IPS_CreateVariable(3);
    IPS_SetParent($DevicesID, $_IPS['SELF']);
    IPS_SetName($DevicesID, "Devices");
    $DeviceList = array();
    $InstanzIDsList = IPS_GetInstanceListByModuleID('{E5BB36C6-A70B-EB23-3716-9151A09AC8A2}');  // Zigbee2MQTT
    foreach ($InstanzIDsList as $InstanzID) {
        $LastSeenID = @IPS_GetObjectIDByIdent('Z2M_LastSeen', $InstanzID);
        if ($LastSeenID != false){
            $Update['Device'] = $InstanzID;
            $Update['Parent'] = IPS_GetName(IPS_GetParent($InstanzID));
            $Update['Name'] = IPS_GetName($InstanzID);
            $Update['LastSeen'] = GetValue($LastSeenID);
            $Update['Max'] = 0;
            $UpdateList[] = $Update;
        }
    }
    SetValue($DevicesID, json_encode($UpdateList));
    IPS_SetScriptTimer($_IPS['SELF'], 10);
}
$TabelleID = @IPS_GetVariableIDByName("Tabelle", $_IPS['SELF']);
if ($TabelleID == false){
    $TabelleID = IPS_CreateVariable(3);
    IPS_SetVariableCustomProfile($TabelleID, "~HTMLBox");
    IPS_SetParent($TabelleID, $_IPS['SELF']);
    IPS_SetName($TabelleID, "Tabelle");
}
$UpdateList = json_decode(GetValue($DevicesID), true);
foreach ($UpdateList as &$Update) {
    $LastSeenID = @IPS_GetObjectIDByIdent('Z2M_LastSeen', $Update["Device"]);
    if ($LastSeenID != false){
        if ($Update['LastSeen'] != GetValue($LastSeenID)){
            $diff = GetValue($LastSeenID) - $Update['LastSeen'];
            if ($diff > $Update['Max']) $Update['Max'] = $diff;
            $Update['LastSeen'] = GetValue($LastSeenID);
        }
    }
}
SetValue($DevicesID, json_encode($UpdateList));
$Zimmer  = array_column($UpdateList, 'Parent');
$Name = array_column($UpdateList, 'Name');
array_multisort($Zimmer, SORT_ASC, $Name, SORT_ASC, $UpdateList);

// HTML ereugen
$HintergrundFarbcode = '000000';
$TextFarbcode = 'FFFFFF';
$TextSize = 14;
$TextSizeTitle = $TextSize + 2;
$TextWeight = 'normal';
$Textausrichtung = 'text-align:left;';

$HTML_CSS_Style = '<style type="text/css">
.bt {border-collapse: separate;border-spacing: 2px;}
.bt td {font-family:Arial, sans-serif;font-size:' . $TextSize . 'px;color:#' . $TextFarbcode . ';' . $Textausrichtung . 'padding:1px 10px;border-style:solid;border-width:1px;overfNOK:hidden;word-break:normal;}
.bt th {font-family:Arial, sans-serif;font-size:' . $TextSize . 'px;color:#' . $TextFarbcode . ';' . $Textausrichtung . 'padding:1px 10px;border-style:solid;border-width:1px;overfNOK:hidden;word-break:normal;}
.bt .tb-title {font-size:' . $TextSizeTitle . 'px;padding:2mm;' . $Textausrichtung . 'background-color:#' . $HintergrundFarbcode . ';color:#' . $TextFarbcode . '}
.bt .tb-content {font-size:' . $TextSize . 'px;font-weight: ' . $TextWeight . ';padding:1mm;' . $Textausrichtung . 'background-color:#' . $HintergrundFarbcode . ';color:#' . $TextFarbcode . '}
</style>';

$HTML = '<html>' . $HTML_CSS_Style;
$HTML .= '<table class="bt"';

$Titel = array();
$Titel = array('Instanz-ID');
$Titel[] = 'Parent';
$Titel[] = 'Name';
$Titel[] = 'DT (sec)';

$HTML .= '<tr>';

$colspan = 1;
foreach ($Titel as $TitelEntry) {
    $HTML .= '<th class="tb-title"><b>' . $TitelEntry . '</b></th>';
    $colspan++;
}
$HTML .= '</tr><tr>';

foreach ($UpdateList as $Update) {
    $HTML .= '<th class="tb-content">' . $Update['Device'] . '</th>';
    $HTML .= '<th class="tb-content">' . $Update['Parent'] . '</th>';
    $HTML .= '<th class="tb-content">' . $Update['Name'] . '</th>';
    $HTML .= '<th class="tb-content">' . $Update['Max'] . '</th>';
    $HTML .= '</tr>';
}
$HTML .= '</table></html>';
$TabelleID = @IPS_GetVariableIDByName("Tabelle", $_IPS['SELF']);
SetValue($TabelleID, $HTML);
?>

Und so sieht z.B. eine Tabelle aus:

Hier kann man sehen das die Zeiten stark variieren.

Wenn man „last_seen“ neu eingeschaltet hat muss man erst 2-3 Tage warten damit alle Geräte „last_seen“ haben und danach dann das Script starten.

Hat man ein Gerät gelöscht oder möchte man ein neues Gerät hinzufügen einfach die Devices-Variable und den ScriptTimer löschen und das Programm erneut starten. Die Variable Tabelle sollte man nicht löschen sonst muss man wieder einen Link ins Web-Front erzeugen.

Die Werte steigern sich im Laufe der Zeit so das man erst nach einigen Tagen aussagekräftige Werte in der Tabelle sieht.

Viel Spaß Ralf

3 „Gefällt mir“

Vielen Dank für das Skript.

Zu wenigen Tagen mal im Vergleich die Zeit meiner Rauchmelder. Anfangs machte mich das (unbegründet) nervös.

Hi,
bei mir sind die Rauchmelder auch eher wenig gesprächig. Ein wenig nervös sollte man trotzdem sein denn in den dazwischen liegenden Monaten kann mehr als ein Haus abbrennen.

Ralf

Hi Ralf,
Danke für das nette Skript.

VG
Stefan

Ich habe schon ein ernstes Wort mit ihm gesprochen aber er reagiert - wie meine Töchter - mit trotzigen Verhalten.
Es scheint ihm egal zu sein, was meine Sichtweise zu dem Thema ist.
Er meldet sich pünktlich, wenn es brennt und meine Bedenken ignoriert er stoisch.

Ich habe 5 Melder und zwei verschiedene Typen (3 melden sich selten und 2 ständig). Bei Tests springen alle sofort an.

Hi,
kannst Du den den Test per IPS auslösen? Wenn ja den Test mal bei allen Nachts um 3 auslösen :rofl:

Ralf

Ich müsste danach um mein Leben fürchten. :face_with_hand_over_mouth:

Super Idee und läuft auf Anhieb :slight_smile: .

„px“ für die Schriftgröße ist nicht unbedingt optimal, da die auf verschiedenen Gerät anders angezeigt werden, mit „em“ ist es universeller :wink: .

Moin Ralf,
danke für den Hinweis. Ich schaue meistens mit PC drauf und da passt es. Mal sehen wie es mit em aussieht.

Ralf

1em ist üblicherweise die „normale“ Schriftgröße des Gerätes.

Moin Namensvetter,
habe es mit em schon gefunden :smiley:
Ralf

1 „Gefällt mir“

Ich habe noch einen komischen Effekt
grafik

die ID ist natürlich nicht doppelt, dass täte mich verwundern :smiley: , aber ich sehe auf Anhieb nicht, weshalb die Zeile zweimal kommt.

Habe ich auch einmal. Hab noch keine Ahnung wo es herkommt.

Ralf Biedermann

Wahrscheinlich irgendein Problem in einer Schleife, aber ich konnte noch nicht detailliert schauen.

Ich habe auch gleich geschaut und keinen offensichtlichen Grund gefunden. Es geschieht beim Erzeugen der Tabelle.

Ralf

Danke für das coole Script. Funktioniert super.

Der höchste InstanzenID-Wert ist bei mir der doppelte.

Grüße
Björn

Hi,
das mit den doppelten Werten verstehe ich nicht.

Mein Script läuft jetzt ja schon eine Woche und ich finde es eigentlich ziemlich erschreckend das auch Geräte mit Stromanschluss, wie Steckdosen/Lampen, sich nur alle paar Stunden melden.

Ralf

Ich denke, dass das nur eine gefühlte Unsicherheit ist.
Wenn sich nichts ändert, besteht ja keine echte Dringlichkeit, sich zu melden.

Ich kenne aber auch dieses Unbehagen. :face_with_peeking_eye:

LG

Hi,
was ich noch erstaunlich finde ist das selbst Geräte mit Stromanschluss meistens nur alle 3 Stunden eine Meldung absenden. Da hatte ich deutlich öfter erwartet.

Ralf

Als Kontrast dazu meine Radar Bewegungsmelder, die das Netz mit Meldungen fluten. Bei denen steht bei „zuletzt gesehen“ immer „just now“. :smile: