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