smarthome-tricks.de

Eigenes Logging in ioBroker

In diesem Artikel zeige ich Dir, wie Du Dein eigenes Logging in ioBroker implementieren kannst.

In unserem Smart-Home hatte ich die Idee, bestimmte Ereignisse in Form eines eigenen Protokolls zu speichern. Derzeit dokumentiere ich mir z.B. die Türstatus oder Status zur automatischen Beleuchtung. Im Artikel zeige ich Dir, wie ich mir dazu einen eigenen Datenpunkt, sowie eine globale Funktion implementiert habe.

Hier zunächst meine Anforderungen an das Protokoll:

Mit diesen Anforderungen beginnen wir nun mit der Erstellung der benötigten Datenpunkte.

Im ersten Schritt wechseln wir nun in den Bereich Scripts und erstellen uns ein neues JavaScript. In das Script kopieren wir den folgenden Script-Code:

const EventListDestination = "javascript.0.SystemEventList.";

createState(EventListDestination + "EventList", "", false, { read: true, write: true, name: "Event-Liste", type: "string", role: "text", def: "" });
createState(EventListDestination + "NextEventId", 0, false, { read: true, write: true, name: "Nächste Event-Id", type: "number", def: 0 });

Das Script ist ein kleines Hilfsscript, mit dem wir uns im ersten Schritt die benötigten Datenpunkte für die Logging anlegen. In der 1. Zeile des Scripts wird dazu eine Konstante definiert, welche den Speicherort der neuen Datenpunkte angibt. Du kannst hier selbstverständlich auch einen anderen Speicherort definieren. Im nächsten Schritt werden mit den beiden createState Aufrufen ein Datenpunkt für die eigentliche Protokoll-Liste (EventList) sowie ein Datenpunkt für die maximale Protokoll-Id angelegt.

Nach dem Aktivieren und Speichern des Scripts sollten nun nach der ersten Ausführung die folgende Datenpunkte im entsprechenden Speichertort angelegt worden sein. Du kannst die Datenpunkte optional auch händisch anlegen, ich löse so etwas aber in der Regel mittels einem kleinen Script, welches ich nach dem einmaligen Ausführen dann wieder deaktiviere. Im Screenshot siehst Du hier nun die angelegten Datenpunkte für das Logging.

Im nächsten Schritt wechseln wir wieder in den Bereich Scripte und aktivieren nun den Expertenmodus. Den Expertenmodus benötigen wir, um ein neues globales Script anlegen zu können. Wir erstellen uns das Script global, sodass wir die Protokollierung in allen Scripts nutzen können.

Nach dem wir nun den Expertenmodus aktiviert haben, wird in der Liste der verfügbaren Scripts ein weiterer Ordner global eingeblendet. Unterhalb von diesem Ordner werden alle globalen Scripts gespeichert. Wir markieren nun den Ordner und klicken auf das markierte Plus-Symbol.

Als Script-Art wählen wir hier Javascript und klicken auf die markierte Schaltfläche hinzufügen.

Im nächsten Schritt müssen wir für das neue Script noch einen Namen definieren. Ich habe als Name SystemEvents gewählt und mit Ok das Script gespeichert.

Jetzt beginnen wir mit der eigentlichen Implementierung der Protokoll-Funktion. Dazu habe ich zunächst wieder über die Konstante den Speicherort der Protokollierung festgelegt. Falls Du oben einen anderen Speicherort gewählt hast, muss dieser dann hier ebenfalls angepasst werden.

Mit der Funktion createEventLog wird der eigentliche Eintrag in den Protokollierungs-Datenpunkt geschrieben. Die Funktion bekomme hierzu zwei Paramter. Im ersten Paramter habe ich den Typ des Eintrags (Info, Fehler, usw…) definiert. Mit dem zweiten Parameter wird die eigentliche Meldung übergeben. Die Funktion ermittelt dann die nächste Event-Id für die fortlaufende Nummerierung der Einträge, sowie den aktuellen Timestamp für die Zeitangabe. Hierzu wird die Zeitangabe in das Format TT.MM.JJ hh:mm:ss formatiert. Anschließend wird der neue Eintrag an die bestehenden Protokoll-Einträge vorangestellt. Der neueste Eintrag steht somit immer oben im Protokoll.

const EventListDestination = "javascript.0.SystemEventList.";

function createEventlog(EventType, EventText) {
  let EventList = getState(EventListDestination + "EventList").val;
  let EventId = getState(EventListDestination + "NextEventId").val;
  let EventDateTime = formatDate(getDateObject((new Date().getTime())), "TT.MM.JJ hh:mm:ss");

  EventId = EventId + 1;
  setState(EventListDestination + "NextEventId", EventId);
  
  let FormatedEventId = ("00000" + EventId).slice(-5);
  
  let EventLog = FormatedEventId + " - " + EventDateTime + " - " + EventType + " - " + EventText;
  EventList = EventLog + "<br>" + EventList;
  
  setState(EventListDestination + "EventList", EventList);
}

Wir können das neue globale Script nun speichern und aktivieren. Nach dem Speichern werden alle angelegten Scripte einmalig ausgeführt, da eine Änderung an den globalen Scripten gemacht wurde. Grundsätzlich solltest Du in den globalen Scripten möglichst wenig Scripte implementieren, da dieser Code bei jedem Script vorangestellt und ausgeführt wird. Gerade bei vielen globalen Scripts kann dies auf Dauer zu Performance-Problemen führen.

Wir können nun in allen Scripts mit dem folgenden Aufruf einen Eintrag in unseren Protokoll-Datenpunkt schreiben:

Beispiel-Aufruf 1:
In diesem Beispiel wird eine Info-Eintrag geschrieben.

createEventlog("Info", "Test Nachricht");

Beispiel-Aufruf 2:
Im zweiten Beispiel können wir auch Fehler z.B. Low-Bat Meldungen dokumentieren.

createEventlog("Fehler", "Fehler-Nachricht");

Im folgenden Scriptcode habe ich nun die Funktion zur Dokumentation eines Tür-Status implementiert. Im Trigger auf den STATE Datenpunkt unserer Haustür habe ich hier den aktuellen Zustand im Protokoll gespeichert.

on({id: "hm-rpc.0.XXXXXXXXX.STATE", change: "ne"}, function (obj) {
  var value = obj.state.val;

  if ( value === true ) {
    createEventlog("Info", "Haustür wurde geöffnet");
  } else {
    createEventlog("Info", "Haustür wurde geschlossen");
  }  
});

Im nächsten Schritt schauen wir uns nun die Visualisierung des Protokolls auf VIS an. Dazu werde ich nun meine System-View um ein weiteres HTML-Widget erweitern.

Im HTML-Code des Widgets fügen wir nun das folgende Object-Binding ein:

{javascript.0.SystemEventList.EventList}

Das Widget in VIS sieht nun wie folgt aus:

In der Visualisierung wird nun der Inhalt der Protokollierung wie folgt angezeigt. Im Protokoll ist vorne die eindeutige Nummer zu sehen. Als nächstes folgt der Zeitstempel des Eintrags sowie die Art und die eigentliche Meldung.

Ich finde diese Form der Protokollierung schon mal sehr praktisch. In einem späteren Teil werden wir dann noch Erweiterungen wie z.B. verschiedene Ansichten vorsehen. Ich denke gerade Filter auf die Art der Einträge sind ein wichtiges Thema.

Ich hoffe ich konnte Dir mit diesem Artikel bereits einen ersten Einblick in die Möglichkeiten der eigenen Protokollierung in ioBroker geben. Über Kommentare, Fragen oder Anregungen freue ich mich.

Die mobile Version verlassen