das ical script hat eigenen thread bekommen
bitte testen @bergjet @Stephan-Schleich
https://forum.iobroker.net/topic/40691/html-tabelle-für-ical-adapter-mehrere-instanzen
@ple
Ich greife mal einen Ansatz aus dem anderen Thread auf zur Erstellung der Alias-Datenpunkte mit gleichen Eigenschaften für einen Selektor:
var typeAlias, read, write, nameAlias, role, desc, min, max, unit, states, custom;
function createAlias(idSrc, idDst) {
if(existsState(idDst)) log(idDst + ' schon vorhanden !', 'warn');
else {
var obj = {};
obj.type = 'state';
obj.common = getObject(idSrc).common;
obj.common.alias = {};
obj.common.alias.id = idSrc;
if(typeAlias) obj.common.type = typeAlias;
if(obj.common.read !== false && read) obj.common.alias.read = read;
if(obj.common.write !== false && write) obj.common.alias.write = write;
if(nameAlias) obj.common.name = nameAlias;
if(role) obj.common.role = role;
if(desc) obj.common.desc = desc;
if(min !== undefined) obj.common.min = min;
if(max !== undefined) obj.common.max = max;
if(unit) obj.common.unit = unit;
if(states) obj.common.states = states;
if(custom && obj.common.custom) obj.common.custom = custom;
obj.native = {};
setObject(idDst, obj);
}
}
let meldungen = [
{trigger: "hm-rpc.xxxxxx", message: "Fenster im Schlafzimmer ist offen" },
{trigger: "XXXXXXX", check: "val >= 100", message: "Jalousie im Schlafzimmer ist oben" },
{trigger: 'ping.0.192_168_10_1'/*Steuerung*/, check: "!val", message: "Server nicht erreichbar" }
]
typeAlias = 'boolean';
role = 'indicator';
custom = [];
for(let i = 0; i < meldungen.length; i++) {
let idOrigin = meldungen[i].trigger;
let idAlias = 'alias.0.Meldungen.M' + (i + 1);
nameAlias = meldungen[i].message;
read = meldungen[i].check;
createAlias(idOrigin, idAlias);
}
EDIT: Die Auswertung der Alias-Datenpunkte kann dann mit einem einfachen Script erfolgen.
const idsMsg = $('alias.0.Meldungen.*');
function schleife() {
let arrMsg = []; // Array mit allen Namen, deren DP den Wert true hat
idsMsg.each(function(id, i) {
if(getState(id).val) arrMsg.push(getObject(id).common.name);
});
// Array für Darstellung auswerten
}
idsMsg.on(schleife); // Triggert bei Wertänderung eines Datenpunktes
schleife(); // Scriptstart
Erstmal vielen herzlichen Dank für deine Unterstützung und Beispiele.
Ich glaube, mit den Alias bin ich doch auf dem falschen Wege, oder ich schiebe es mal weiter nach hinten.
Ist aber sehr interessant für andere Sachen.
Ich versuche es mal wieder wie am Anfang, somit benötige ich, wenn es denn klappt. keine Datenpunkte.
let Meldung = [
{trigger: 'javascript.0.Test.test', Check: "true oder false oder Wert in %", message: "test" },
{trigger: 'ping.0.10_170_21_254'/*Server*/, Check: "true oder false oder Wert in %", message: "Server nicht erreichbar" },
{trigger: 'ping.0.192_168_10_1'/*Steuerung*/, Check: "true oder false oder Wert in %", message: "Steuerung nicht erreichbar" },
]
on({id: Meldung.trigger, change: "ne" }, function () {
log(" hat mal ausgelöst")
})
Ich versuche gerade auf das array Meldung den trigger zu reagieren. Bei einem Array wie diesen hier funktioniert das auch.
let Meldung = ['ping.0.192_168_10_1', 'javascript.0.Test.test', 'ping.0.10_170_21_254' ]
Es es überhaupt möglich da irgendwie drauf zu reagieren mit each oder sowas?
Wenn ja, dann würde ich dadrin die Prüfung ablaufen lassen und per Push die Meldungsjson zusammenbauen oder entfernen lassen.
Gruß und Danke
schön mal wieder mehr Zeit für den iobroker zu haben.
Nicht das du denkst, ich würde mit deinen Informationen nichts anfangen
Ich bin noch mal zurück zum Anfang gegangen und habe mir was zusammengebastelt. Hat zwar einige Nachmittage gebraucht, aber der Start ist gemacht und ich glaube damit komme ich zum Ziel meines Vorhaben.
Könnte man auch für Fenstersensoren usw. benutzen, naja, hoffe ich zumindest.
Es ist noch am Anfang, ich weiß auch garnicht wie dreckig ich das programmiert habe ;-), aber über Ratschläge wäre ich sehr dankbar, man lern ja nie aus.
Was noch fehlt.
var pfad = "javascript." + "0.Log.Meldung.";
var output_json = pfad + "output_json"
var Aktor_1 = pfad + "Aktor_1"
var Aktor_2 = pfad + "Aktor_2"
var Aktor_3 = pfad + "Aktor_3"
var Aktor_4 = pfad + "Aktor_4"
createState(output_json,"", {
name: "output_json",
desc: "",
type: "string",
});
createState(Aktor_1, false, {
name: "Aktor 1",
desc: "",
type: "boolean",
});
createState(Aktor_2, false, {
name: "Aktor 2",
desc: "",
type: "boolean",
});
createState(Aktor_3, false, {
name: "Aktor 3",
desc: "",
type: "boolean",
});
createState(Aktor_4, 0, {
name: "Aktor 4",
desc: "",
type: "number",
});
let json = []
let meldung = [
{ trigger: 'javascript.0.Log.Meldung.Aktor_1'/*Aktor 1*/, check1: "==true", check2: "==false", message: "Aktor 1 mit ist true" },
{ trigger: 'javascript.0.Log.Meldung.Aktor_2'/*Aktor 1*/, check1: "==true", check2: "==false", message: "Aktor 2 mit ist true" },
{ trigger: 'javascript.0.Log.Meldung.Aktor_3'/*Aktor 1*/, check1: "==true", check2: "==false", message: "Aktor 3 mit ist true" },
{ trigger: 'javascript.0.Log.Meldung.Aktor_4'/*Aktor 1*/, check1: '>=50', check2: "<51", message: "Aktor 4 ist über 50%" },
]
meldung.forEach(meld => {
on({ id: meld.trigger, change: "ne" }, function () {
let trigger = getState(meld.trigger).val
// Überprüfung boolean
if (eval('' + trigger + meld.check1) && (json.indexOf(meld.message) == -1)) {
json.push(meld.message)
} else if (eval('' + trigger + meld.check2) && json.indexOf(meld.message) >= 0) {
json.splice(json.indexOf(meld.message), 1)
}
log(json.indexOf(meld.message))
log(json)
setState(output_json, JSON.stringify(json))
})
})
Tja, leider hänge ich am nächsten Problem.
Ich muss wohl im Array ein Object pushen, damit ich später meine Table direkt bekomme.
Nur leider finde ich nicht heraus, wie man später in dem Array nach schon bereits existierende Meldung suchen kann und diese auch aus dem Objekt wieder löschen kann, falls der Aktor wieder auf false geht.
Das Script von Mic
https://github.com/Mic-M/iobroker.logfile-script#23-script-einstellen
ist schon sehr hilfreich, aber leider für mich nicht nachvollziehbar.
Hat vielleicht jemand noch einen Ansatz oder eine Idee?
var pfad = "javascript." + "0.Log.Meldung.";
var output_json = pfad + "output_json"
var output_raw = pfad + "output_raw"
var Aktor_1 = pfad + "Aktor_1"
var Aktor_2 = pfad + "Aktor_2"
var Aktor_3 = pfad + "Aktor_3"
var Aktor_4 = pfad + "Aktor_4"
createState(output_json, "", {
name: "output_json",
desc: "",
type: "string",
});
createState(output_raw, "", {
name: "output_raw",
desc: "",
type: "string",
});
createState(Aktor_1, false, {
name: "Aktor 1",
desc: "",
type: "boolean",
});
createState(Aktor_2, false, {
name: "Aktor 2",
desc: "",
type: "boolean",
});
createState(Aktor_3, false, {
name: "Aktor 3",
desc: "",
type: "boolean",
});
createState(Aktor_4, 0, {
name: "Aktor 4",
desc: "",
type: "number",
});
let arr = []
let arr_test = []
let meldung = [
{ trigger: 'javascript.0.Log.Meldung.Aktor_1'/*Aktor 1*/, check1: "==true", check2: "==false", message: "Aktor 1 mit ist true" },
{ trigger: 'javascript.0.Log.Meldung.Aktor_2'/*Aktor 1*/, check1: "==true", check2: "==false", message: "Aktor 2 mit ist true" },
{ trigger: 'javascript.0.Log.Meldung.Aktor_3'/*Aktor 1*/, check1: "==true", check2: "==false", message: "Aktor 3 mit ist true" },
{ trigger: 'javascript.0.Log.Meldung.Aktor_4'/*Aktor 1*/, check1: '>=50', check2: "<51", message: "Aktor 4 ist über 50%" },
]
meldung.forEach(meld => {
on({ id: meld.trigger, change: "ne" }, function () {
let trigger = getState(meld.trigger).val
let obj = {
"Datum": "",
"Meldung": meld.message
};
// Überprüfung boolean
if (eval('' + trigger + meld.check1) ) { //Meldung ist nicht vorhanden
log("schreiben")
arr.push(obj)
// log(arr.indexOf(obj))
// log(arr)
} else if (eval('' + trigger + meld.check2) ) {
arr.splice(arr.indexOf(obj.Meldung), 1)
log("löschen")
}
log(arr.indexOf(meld.message))
log(arr)
})
})
so würde ich das Problem angehen:
var meldung = [
{ trigger: 'javascript.0.Log.Meldung.Aktor_1'/*Aktor 1*/, check1: "==true", check2: "==false", message: "Aktor 1 mit ist true", subscription:0 },
{ trigger: 'javascript.0.Log.Meldung.Aktor_2'/*Aktor 1*/, check1: "==true", check2: "==false", message: "Aktor 2 mit ist true", subscription:0 },
{ trigger: 'javascript.0.Log.Meldung.Aktor_3'/*Aktor 1*/, check1: "==true", check2: "==false", message: "Aktor 3 mit ist true", subscription:0 },
{ trigger: 'javascript.0.Log.Meldung.Aktor_4'/*Aktor 1*/, check1: '>=50', check2: "<51", message: "Aktor 4 ist über 50%", subscription:0 },
]
for (var a=0;a<meldung.length;a++) {
meldung[a].subscription = on({ id: meldung[a].trigger, change: "ne" }, main);
}
main(obj) {
if (!meldung || meldung.length==0) return;
var a = 0;
for (a=0;a<meldung.length;a++) {
if ( meldung[a].trigger == obj.Id ) break;
}
if (a==meldung.length) return;
// entferne trigger;
var meld = meldung[a];
if (meld.subscription) unsubscribe(meld.subscription);
})
ungetestet und kann Syntaxfehler enthalten
Ups das war nicht die aktuelle Frage. sry
Zur aktuellen Frage könnte das klappen. Ist aber ebenfalls ungetestet
} else if (eval('' + trigger + meld.check2) ) {
arr = arr.filter(({"Meldung"}) => Meldung != obj.Meldung);
log("löschen")
}
@ple sagte:
arr.splice(arr.indexOf(obj.Meldung), 1)
funktioniert nicht wie erwartet ? Dann verwende eine Schleife über arr.
Hab gerade etwas ähnliche gebraucht:
function sendMsg(f, msg) {
if (messageArray.findIndex(function(a){ return (a.from == f && a.msg == msg)}) != -1) return;
messageArray[0]={"from":f,"msg":msg};
@ticaki said in Array erstellen mit Prüfung für Json Tabelle:
Hab gerade etwas ähnliche gebraucht:
function sendMsg(f, msg) { if (messageArray.findIndex(function(a){ return (a.from == f && a.msg == msg)}) != -1) return; messageArray[0]={"from":f,"msg":msg};
Kannst du mir vielleicht dein ganzen script zur Verfügung stellen? leider verstehe ich einfach nicht, was da genau passiert.
Durch try and error bin ich mit meinem jetzt so weit.
var pfad = "javascript." + "0.Log.Meldung.";
var output_json = pfad + "output_json"
var Aktor_1 = pfad + "Aktor_1"
var Aktor_2 = pfad + "Aktor_2"
var Aktor_3 = pfad + "Aktor_3"
var Aktor_4 = pfad + "Aktor_4"
createState(output_json, "", {
name: "output_json",
desc: "",
type: "string",
});
createState(Aktor_1, false, {
name: "Aktor 1",
desc: "",
type: "boolean",
});
createState(Aktor_2, false, {
name: "Aktor 2",
desc: "",
type: "boolean",
});
createState(Aktor_3, false, {
name: "Aktor 3",
desc: "",
type: "boolean",
});
createState(Aktor_4, 0, {
name: "Aktor 4",
desc: "",
type: "number",
});
let arr = []
let arr_test = []
let meldung = [
{ trigger: 'javascript.0.Log.Meldung.Aktor_1'/*Aktor 1*/, debug: "Störung", check1: "==true", check2: "==false", message: "Aktor 1 mit ist true" },
{ trigger: 'javascript.0.Log.Meldung.Aktor_2'/*Aktor 1*/, debug: "Störung", check1: "==true", check2: "==false", message: "Aktor 2 mit ist true" },
{ trigger: 'javascript.0.Log.Meldung.Aktor_3'/*Aktor 1*/, debug: "Störung", check1: "==true", check2: "==false", message: "Aktor 3 mit ist true" },
{ trigger: 'javascript.0.Log.Meldung.Aktor_4'/*Aktor 1*/, status: "error", check1: '>=50', check2: "<51", message: "Aktor 4 ist über 50 %" },
]
meldung.forEach(meld => {
on({ id: meld.trigger, change: "ne" }, function () {
let trigger = getState(meld.trigger).val
let trigger_ts = formatDate(getDateObject(getState(meld.trigger).ts), "JJJJ.MM.TT SS:mm:ss");
let obj = {
"Datum": trigger_ts,
"Art": meld.debug,
"Meldung": meld.message
};
let alarm = false
arr.forEach(function (a, Index) {
if (a.Meldung == obj.Meldung) {
alarm = true
if (eval('' + trigger + meld.check2)) {
arr.splice(Index, 1)
//log("löschen")
}
} else {
alarm = false
}
})
if (eval('' + trigger + meld.check1) && (!alarm)) {
arr.push(obj)
}
//log(arr)
setState(output_json, JSON.stringify(arr))
})
})
Ich weiß aber, dass die Werte bei iobroker neustart nicht eingelesen werden und das sortieren klappt auch noch nicht.
Eigentlich eine feine Sache, um sich den Status von Datenpunkten ausgeben zu lassen und die direkt visualisieren lassen zu können. Noch besser wäre es, wenn man das irgendwie mit dem Script für Logs realisieren könnte, da man dort direkt auch Filtern kann und eine ganze Menge mehr Sachen machen, aber leider zu hoch für mich.
Gruß
@ple sagte in Array erstellen mit Prüfung für Json Tabelle:
mit .findIndex kannst du eine Funktion aufrufen, in der du prüfen kannst ob das übergebene Object(oder was auch immer) deiner Suche entspricht. Ich suche hier den Eintrag in dem from und msg == den übergebenen Werten ist und geben über return true zurück, wenn dem so ist.
messageArray.findIndex(function(a) {
return (a.from == f && a.msg == msg)
})
Ich hab nen Display der 3 Zeilen anzeigen kann und dieses Script verwaltet das.
var messageArray = [{},{},{}];
messageArray[0] = {"from":"","msg":"-1"};
messageArray[1] = {"from":"","msg":"-1"};
messageArray[2] = {"from":"","msg":"-1"};
onMessage("DisplayMessage", function(data,result){
var msgfrom = data[2];
var mode = data[1];
var msg = data[0].toString();
if (msg.length == 0 && mode !=0) return;
var done = false;
switch (mode) {
case 0:
done = deleteAllMsg(msgfrom);
break;
case 1:
done = sendMsg(msgfrom,msg);
break;
case 2:
done = deleteMsg(msgfrom,msg);
break;
}
if (done) {
var check=true;
while(check) {
check=false;
var first=-1;
for (var i=0; i<3;i++){
if (messageArray[i].msg != '-1' && first != -1) {
messageArray[first] = messageArray[i];
log(messageArray[i].msg+' swap int:'+ i +' '+first);
check = true;
break;
}
if (messageArray[i].msg=='-1') {
first = i;
}
}
}
for (var i=0; i<messageArray.length;i++){
if (typeof messageArray[i].msg == 'number') {
setState('mqtt.1.display.show.Nachricht.msg'+(i+1), '-1');
} else {
setState('mqtt.1.display.show.Nachricht.msg'+(i+1), messageArray[i].msg);
}
}
}
});
function sendMsg(f, msg) {
if (messageArray.findIndex(function(a){ return (a.from == f && a.msg == msg)}) != -1) return; // keine doppelten Einträge
var a = 2;
while (a--) {
messageArray[a] = messageArray[a-1];
}
messageArray[0]={"from":f,"msg":msg};
return true;
}
function deleteAllMsg(f) {
for (var a=0;a<3;a++){
if (messageArray[a].from == f) messageArray[a]={"from":"","msg":"-1"};
}
return true;
}
function deleteMsg(f,msg) {
for (var a=0;a<3;a++){
if (messageArray[a].msg==msg && messageArray[a].from == f ) {
messageArray[a]={"from":"","msg":"-1"};
return true;
}
}
return false;
}