Eigenes Logging in ioBroker – Teil 4

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 werde ich ich ein neues, angepasstes Script mit den Funktionsupdates zeigen:

Hier zunächst meine Basis-Anforderungen an das Protokoll:

  • Protokoll-Eintrag mit folgenden Angaben:
    – Eindeutige, fortlaufende Vorgangsnummer (ID)
    – Datum- und Zeitangabe des Eintrags
    – Art des Protokoll-Eintrags (Fehler, Info, usw…)
    – Protokoll-Text
  • Protokoll muss nachträglich leerbar sein.
  • Einfacher Aufruf im JavaScript-Code.

Im 1. Teil der Artikelreihe habe wir bereits ein Script dazu implementiert. Im Laufe der Zeit kamen nun aber weitere Anforderungen dazu, welche im neuen Script berücksichtigt wurden:

  • Einstellbar maximale Anzahl an Log-Einträgen
    Hier gab es bei mir in meiner Umgebung sowie auch bei einigen Anwendern das Problem von zu langen Ladezeiten der VIS. Bei einigen Tausend Datensätzen ist das auch kein Wunder. Daher habe ich hier für eine neue Einstellung (maxEventCount) vorgesehen, mit dem die Anzahl der maximalen Einträge begrenzt werden kann.
  • Mehrfach-Aufruf Problematik (Timing-Problem)
    Wenn in einem Trigger oder sonstigen Script mehrere Aufrufe der Funktion createEventLog() hintereinander implementiert wurden, dann kam hier aufgrund eines Timing-Problems nur der letzte Log-Eintrag im Datenpunkt an. Dies kann einfach mit dem separaten Beispiel-Code umgangen werden.

Für die Installation des Scripts muss einfach das bestehende Script mit dem folgenden Script-Code ersetzt werden. Bitte beachte dabei, dass bei einer Änderung des globalen Code-Bereichs alle Scripte automatisch einmalig ausgeführt werden. Hier nun der neue Script-Code für die Logging-Funktionalität:

const EventListDestination = "javascript.0.SystemEventList.";
const maxEventCount = 500;
 
function createEventlog(EventType, EventText) {
  let EventList = getState(EventListDestination + "EventList").val;
  
  // Nur die letzten x Einträge im Script belassen
  let eventList = EventList.split('<br>');
  let eventCount = eventList.length;
  let newEventList = "";

  for (var i = 0; i < eventCount; i++) {
    if ( i < (maxEventCount-1) ) {
      newEventList = newEventList + "<br>" + eventList[i];
    } else {
      break;
    }
  }
  
  EventList = newEventList;
 
  // Neue Event-Id und Zeitpunkt ermitteln
  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 + EventList;
   
  setState(EventListDestination + "EventList", EventList);
}

Beispiel-Code für das mehrmalige Aufrufen der createEventLog() Funktion:

function sleep(milliseconds) {
 return new Promise(resolve => setTimeout(resolve, milliseconds));
}

async function createMultipleLogs() {
  createEventlog("Info", "Test Nachricht 1");
  await sleep(100);
  createEventlog("Info", "Test Nachricht 2");
  await sleep(100);
  createEventlog("Info", "Test Nachricht 3");
  await sleep(100);    
}

createMultipleLogs();

Vielen Dank für euer Feedback. Bei weiteren Fragen oder Anregungen gerne melden 🙂

Matthias Korte

Hauptberuflich Software-Entwickler und seit einigen Jahren Smart-Home Fan. Angefangen hat alles mit einem RaspberryMatic und einer schaltbaren Steckdose. Mittlerweile habe ich einige Steckdosen, Sensoren, und Thermostate sowie ioBroker zur Visualisierung im Einsatz.

5 Gedanken zu „Eigenes Logging in ioBroker – Teil 4

  • 14. Februar 2021 um 11:36
    Permalink

    Hallo Mathias,
    die Idee mit dem eigenen Logging ist ja echt Prima. Habe ich gleich bei mir in Blockly implementiert.
    Nun habe ich aber Blockly Skripte, welche parallel getriggert werden.
    Da ist es dann offensichtlich so, dass das zuletzt getriggerte Skript auf dem Log erscheint.
    Im Teil 4 beschreibst du eine Lösung dazu in Javascript. Wie kann ich diese in Blockly implementieren?
    Funktioniert die in Teil 4 beschriebene Lösung auch Skriptübergreifend?

    Vielen Dank für diesen tollen Blog und deine Hilfe.

    Grüße
    Sascha

    Antwort
  • 14. Februar 2021 um 19:21
    Permalink

    Hallo Mathias,
    vielen Dank für das tolle Skript. Ich habe die Blockly Variante nun in mein System integriert.
    Globales Skript aus Teil 4 und den Blockly Aufruf aus Teil 2.
    Nach ein paar Tagen viel leider auf, dass bei parallel angestoßenen Skripten immer nur das Log des letzten aufgeführt wird. Gibt es eine Möglichkeit dies auch in Blockly zu verhindern?
    Ich könnte natürlich manuelle Zeitversätze da rein bringen, was aber auf Dauer nicht zielführend wäre.
    Hast du vielleicht ne Idee?

    Grüße
    Sascha

    Antwort
    • 18. Februar 2021 um 6:40
      Permalink

      Hallo Sascha,

      ich prüfe das, und werde es ergänzen.

      LG Matthias

      Antwort
      • 18. Februar 2021 um 13:02
        Permalink

        Prima,
        würde mich freuen, wenn dass das Problem lösbar ist.
        Wenn du noch Informationen benötigst, melde dich gerne.

        Grüße
        Sascha

        Antwort
  • 8. Juli 2021 um 20:06
    Permalink

    Hallo Matthias
    Zunächst einmal Danke für deine Anleitungen.
    Die Einbindung in meinem iobroker hat hervorragend geklappt, jedoch habe ich das Problem, dass mir als Zeitstempel des Ereignisses nicht die aktuelle Zeit (Sommerzeit) sondern die MEZ (UTC+1) anzeigt wird. Hast Du einen Tipp für mich, wie ich das korrigieren kann?
    Gruß
    Simon

    Antwort

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.