// Erstellt Ereignislisten
//========================
//
// Version: 0.2.3 (27.05.2018)
// Autor: ruhr70
// Skript im Forum: https://forum.iobroker.net/viewtopic.php?f=21&t=13209#p139023
// Skript auf Github: n.v.
//
// Events können über die globale Funktion event(text,list); geschrieben werden
// Events werden mit der globalen Funktion
// event(text,liste) als Text in die ID: pfad+liste+".event" geschrieben
// ohne Angabe wird die Liste "default" verwendet
// je Liste werden folgende Datenpunkte erstellt:
// .eventlistStr -> Liste als String, z.B. für Telegram
// .eventlistHTML -> Liste mit html Tags, wenn übergeben und <br> als Zeilenumbruch, z.B. für VIS
// .eventlistArr -> die Liste als Array (ein String je Eintrag) für das Skript. Kann auch anderweitig verwendet werden.
// .event -> wird durch die globale Funktion event() beschrieben. Oder auf anderem Wege. der Inhalt wird in die entsprechende Liste als Eintrag übernommen.
// Erstellung eines Eintrags in einer Liste:
// 1.) die Datenpunkte mit der Endung .event können direkt beschrieben werden
// 2.) mit der globalen Funktion event(text,liste)
// globale Funktion event(text,liste) (extra Skript, unter globale Skripte zu speichern)
// --------------------------------------------------------------------------------------
// text: der Eintrag, der mit dem aktuellen Zeitstempel in die Liste geschrieben werden soll
// liste: (optional, wenn nicht angegeben, wird die Liste "default" verwendet)
// event("<b>Tür</b> geöffnet");
// erstellt in der Liste "default" in der html Liste einen Eintrag, mit fettgeschriebener "Tür"
// erstellt in der Liste "default" in der str Liste einen Eintrag "Tür geöffnet" ohne Formatierung
// Ereignislisten
// --------------
// "default" -> Liste muss vorhanden sein, wird verwendet, wenn in der globalen Funktion nicht angegeben
// Listen "Montag" bis "Sonntag": Tageslisten. Für jeden Tag wird eine neue Lsite begonnen
// "heute" - Einträge vom heutigen Tage werden, wenn geünscht, zusätzlich in die Liste "heute" geschrieben
// plus eigene Listen
// Changelog:
// ----------
// 0.2.2 Colorlog entfernt, da im aktuellem Admin 3 nicht mehr unterstützt
// Schnell aufeinanderfolgende Events in einer Liste wurden nicht erfasst. Umstellung von Datenpunkt auf Variable
// 0.2.1 Anzeige Tagestart "neuer Tag" korrigiert
// 0.2.0 Anpassungen durch Apollon77 (danke!):
// - Subscriptions werden nun nach dem Callback und nicht nach dem TImer aufgerufen
// 0.1.1 String Tageswechsel korrigiert, Link zum Forum
// 0.1.0 Veröffentlichung im Formu
// ========================================================================================
// Individuelle Konfiguration
// ========================================================================================
var defaultListe = "default"; // Liste, die verwendet wird, wenn im event() nicht angegeben.
var pfad = "Ereignisliste"+"."; // Pfad, in dem die Listen angelegt werden sollen
// Defaultwerte, wenn bei Listen im JSON nicht definiert
var defaultLaenge = 50; // default: maximale Anzahl von Ereignissen, wenn im JSON nicht angegeben
var defaultNeusteOben = true; // default: neuste Nachrichten oben true
var defaultTagesstart = true; // default: soll ein Tagesstempel in der Liste zum Start des Tages eingefügt werden
var defaultInWochenTag = true; // default: Listeneintrag auch bei der Tagesliste ("heute") und dem heutigen Wochentag
var defaultZeitstempel = 'DD.MM. hh:mm'; // Default Zeitstempel (Formate, wie bei der ioBroker Javascript FUnktion formatDate())
var trennerZeitstempel = " "; // Trenner zwischen Zeitstempel und Text
function tagesstartTxt() {
return "##### " + wochentagStr() + ", den " + formatDate(new Date(), "DD.MM.JJJJ") + " #####";
}
// Log Einstellungen für das Skript
var logOn = false; // Logging für das Skript einschalten
// Definition der Ereignislisten:
// ==============================
// laenge: max. Anzahl der Einträge. Danach wird der älteste Eintrag ersetzt.
// neusteOben: true -> neuster Eintrag erfolgt oben, false -> neuster EIntrag erfolgt unten
// tagesstart: zum Tagesstart wird ein Eintrag mit Wochentag und Datum erzeugt
// inWochentag true -> Einträge für diese Liste werden in die Liste des jeweiligen Wochentags und in die Liste "heute" geschrieben
// zeitstempel default, wenn nicht angegeben, Ansonsten String, wie bei der Funktion formateDate()
var listenJson = {
"default": {
"laenge":50,
"neusteOben":true,
"tagesstart":true,
"inWochtag":true
},
"Montag": {
"laenge":50,
"neusteOben":false,
"tagesstart":true
},
"Dienstag": {
"laenge":50,
"neusteOben":true,
"tagesstart":true
},
"Mittwoch": {
"laenge":50,
"neusteOben":true,
"tagesstart":true
},
"Donnerstag": {
"laenge":50,
"neusteOben":true,
"tagesstart":true
},
"Freitag": {
"laenge":50,
"neusteOben":true,
"tagesstart":true
},
"Samstag": {
"laenge":50,
"neusteOben":true,
"tagesstart":true
},
"Sonntag": {
"laenge":50,
"neusteOben":true,
"tagesstart":true
},
"heute": {
"laenge":50,
"neusteOben":true,
"tagesstart":true
},
"rule": {
"laenge":50,
"neusteOben":true,
"tagesstart":true,
"inWochtag":false
}
/*
"test": {
"laenge":10,
"neusteOben":false,
"tagesstart":false,
"inWochtag":false,
"zeitstempel":"YYYY-MM-DD hh:mm"
},
"wichtig": {
"laenge":50,
"neusteOben":true,
"tagesstart":true,
"inWochtag":false
}
*/
};
// ========================================================================================
// Ab hier muss nichts angepasst werden
// ========================================================================================
// Korrektur für 0.2.1
var arrayTage = new Array ("Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag");
var subsError = false;
var triggerArr = [];
var jsonArr = {};
// Korrektur für 0.2.1
Array.prototype.enthaelt = function(a) {
for (var i=0; i<this.length; i++) if (a === this[i]) return true;
return false;
};
function makeJsonArr() {
for (var liste in listenJson) {
jsonArr[liste] = readListEvent(pfad+liste+".eventlistArr");
}
}
// Datenpunkte für die Eventlisten anlegen
function dpAnlegen(callback) {
var stateListe = [];
for (var liste in listenJson) {
var zeitstempel = listenJson[liste].zeitstempel;
if (typeof zeitstempel == "undefined") zeitstempel = defaultZeitstempel;
// Hier wird die Liste als Array angelegt
stateListe.push({id: pfad+liste+".eventlistArr", val:formatDate(new Date(), zeitstempel) + trennerZeitstempel + 'Datenpunkt angelegt', write: false});
// Die Liste als String mit \n
stateListe.push({id: pfad+liste+".eventlistStr", val:"", write: false});
// Die Liste als html-String mit <br>\n für VIS
stateListe.push({id: pfad+liste+".eventlistHTML", val:"", write: false});
/*Aktueller Event*/ // überwachter Datenpunkt
stateListe.push({id: pfad+liste+".event", val:"", write: false});
// Array für die Subscritions der Events je Liste
triggerArr.push("javascript."+instance+"."+pfad+liste+".event");
}
function anlegen() {
if (!stateListe.length) {
if(logOn) log("dpAnlegen() durchgelaufen");
callback();
return;
}
var aktuellerState = stateListe.shift();
createState(aktuellerState.id, aktuellerState.val, {type: 'string', role: 'value', read: true, write: aktuellerState.write}, anlegen);
}
anlegen();
}
function wochentagStr() {
var datumAktuell = new Date();
var wochenTagAktuell = datumAktuell.getDay();
var tagName = arrayTage[wochenTagAktuell];
return tagName;
}
function htmlToStr(html) {
var str = "";
str = html.replace(/( )/ig, " "); // in Leerzeichen umwandeln
// Verbesserung möglich: hier über eine Tabelle (z.B. json) html Sonderzeichenumwandeln
str = html.replace(/(&.*;|<([^>]+)>)/ig, ""); // alle übrigen html Sonderzeichen & html Tags rausfiltern
return str;
}
function readListEvent(id) { // lese ein JSON aus einem string Datenpunkt
var list;
try {
list = JSON.parse(getState(id).val);
} catch (ex) {
list = [];
}
if(!list) list = [];
return list;
}
function writeListEvent(list,id) { // schreibt ein JSON in einen Datenpunkt als String
setState(id, JSON.stringify(list));
}
function getEventsListStr(events) {
var text = '';
for (var i = 0; i < events.length; i++) {
text += (text ? '\n' : '') + htmlToStr(events[i]);
}
return text;
}
function getEventsListHtml(events) {
var text = '';
for (var i = 0; i < events.length; i++) {
text += (text ? '<br>\n' : '') + events[i];
}
return text;
}
// Ereignis in der entsprechenden Liste schreiben
function writeEvent(text,eventlist) {
var neusteOben = listenJson[eventlist].neusteOben;
if (typeof neusteOben == "undefined") neusteOben = defaultNeusteOben;
var laenge = listenJson[eventlist].laenge;
if (typeof laenge == "undefined") laenge = defaultLaenge;
var zeitstempel = listenJson[eventlist].zeitstempel;
if (typeof zeitstempel == "undefined") zeitstempel = defaultZeitstempel;
if(neusteOben) { // Liste oben ergänzen (neusteOben = true)
jsonArr[eventlist].unshift(formatDate(new Date(), zeitstempel)+ trennerZeitstempel + text); // fügt den Text als Event am Anfag der Liste ein **** RK
if (jsonArr[eventlist].length > laenge) jsonArr[eventlist].pop(); // kürzt die Liste hinten, wenn die maximale Länge erreicht ist
} else { // oder Liste unten ergänzen (neusteOben = false)
jsonArr[eventlist].push(formatDate(new Date(), zeitstempel)+ trennerZeitstempel + text); // fügt den Text als Event am Ende der Liste ien **** RK
if (jsonArr[eventlist].length > laenge) jsonArr[eventlist].shift(); // kürzt die Liste oben, wenn die maximale Länge erreicht ist
}
writeListEvent(jsonArr[eventlist], pfad+eventlist+".eventlistArr"); // schreibt das Array der Liste in den Datenpunkt zurück
setState(pfad+eventlist+".eventlistStr",getEventsListStr(jsonArr[eventlist])); // erzeugt aus dem Array den String mit \n für neue Zeilen
setState(pfad+eventlist+".eventlistHTML",getEventsListHtml(jsonArr[eventlist]));// erzeugt aus dem Array den String mit <br>\n für neue Zeilen, html Tags bleiben erhalten
}
// Subscriptions für die Events je Liste
// -----------------------------------------------------------------------------
function setSubscriptions() {
on({id:triggerArr,change:'any'}, function (obj) { // wenn ein neuer Event geschrieben wird
var eventlist = obj.name.replace(pfad,"").replace(".event","");
var inWochentag = listenJson[eventlist].inWochtag;
if (typeof inWochentag == "undefined") inWochentag = defaultInWochenTag;
if (!obj.newState.ack && obj.newState.val) {
if(logOn) log("Event für die Liste '" + eventlist + "' erkannt: " + obj.state.val);
writeEvent(obj.state.val,eventlist);
if(obj.state.val == tagesstartTxt()) return; // 0.2.3 Fix: Tagesstart: nicht noch einmal in eine andere Liste schreiben
if(wochentagStr() != eventlist) { // zusätzlich in die Wochentagsliste schreiben, außer es war ein Eintrag für den Wochentag
if(inWochentag) writeEvent(obj.state.val,wochentagStr()); // nicht schreiben, wenn die Liste von der Wochentagliste ausgenommen ist
}
if(wochentagStr() != "heute") { // zusätzlich in die Tagesliste schreiben, außer es war ein Eintrag für die Liste "heute"
if(inWochentag) writeEvent(obj.state.val,"heute"); // nicht schreiben, wenn die Liste von der Wochentagliste ausgenommen ist
}
}
});
if(logOn) log("Skript: " + name + " -> Subscriptions angelegt");
}
// CRON für Tagesüberschrift und Bereinigung von "heute" und dem aktuellen "Wochentag"
function tagesstart() {
if(logOn) log("Skript: " + name + " -> Tagesstart wird ausgeführt");
for (var liste in listenJson) {
var tagesstart = listenJson[liste].tagesstart;
if (typeof tagesstart == "undefined") tagesstart = defaultTagesstart;
var zeitstempel = listenJson[liste].zeitstempel;
if (typeof zeitstempel == "undefined") zeitstempel = defaultZeitstempel;
if(liste == "heute" || liste == wochentagStr()) {
jsonArr[liste] = [];
setState(pfad+liste+".eventlistArr","[]");
setState(pfad+liste+".eventlistStr","");
setState(pfad+liste+".eventlistHTML","");
if(tagesstart) {
setState(pfad+liste+".event",tagesstartTxt());
}
} else {
if(tagesstart && !(liste == "heute" || arrayTage.enthaelt(liste))) { // Korrektur für 0.2.1
setState(pfad+liste+".event",tagesstartTxt());
}
}
}
}
schedule("0 0 * * *", tagesstart);
// Wird ausgeführt, wenn das Skript gestoppt wird:
// -----------------------------------------------
onStop(function skriptStop () {
if(logOn) log("----------- Skript: " + name + " -> wurde beendet -----------");
// Funktionen, die noch ausgeführt werden sollen, wenn das Skript beendet wurde:
}, 100 /ms/);
// --------------- Script start ---------------- #### Script Start ####
function main() {
// Funktionen, die nach dem Anlagen der Datenpunkte ausgeführt werden sollen:
// ...
makeJsonArr();
if(logOn) log("Skript: " + name + " ist bereit");
}
// Skript start
if(logOn) log("----------- Skript: " + name + " -> gestartet -----------");
dpAnlegen(function() {
setSubscriptions();
main();
});