Javascript auf Webserver

philipp00

Level-1
Beiträge
250
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Hat jemand etwas erfahrung mit Javascript hier?

Habe folgende Problemematik, ich möchte ein Alarmfenster erstellen in meiner Webvisio (sieh Foto)
Wenn ich den Code so ausführe wie unten wird sobald ein Objekt (item) aktiv wird, sprich die If-Anweisung erfüllt, folgendes in der obersten Zeile des Alarmfeld angezeit (siehe Foto)
Die Objekte stellen Fehlermeldungen dar, nun soll es so sein das immer das Objekt an oberster Stelle stehen soll mit dem neusten Zeitstempel (item.timestemp) und das Obekt das vor her an oberster stelle gestanden hat, sofern noch aktiv soll im Alarmfenster auf die zweite Zeile verschoben werden, zusätzlich soll es so sein wenn ein Objekt nicht mehr aktiv ist das dieses von selbst ausgeblendet wird.

Ich hoff ihr könnt mir folgen.


Code:
    console.log(item);
    if(item.state == 1 && item.ActiveStateId == true){
		webMI.gfx.setText("txtAlarmDatum1", "22-09-2020");
		webMI.gfx.setText("txtAlarmbedinung1", item.InputNode);
		webMI.gfx.setText("txtAlarmzeile1", item.eventtext.de);
		webMI.gfx.setText("txtAlarmStatus1", item.ActiveState.de);
		}
	);
	}




Alarmfenster im Browser.JPG
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie soll ich vorgehen? sprich bin auf der Suche nach einem Ansatz wie ich es hinkriege das immer das aktuellste Objetkt auf der Linie Pos1 angezeigt wird, das zwei aktuellste auf Pos 2 und das dritte aktuellste auf pos 3. und alle ältern nicht mehr angezeigt werden.
 
Wenn deine Alarme als Array vorliegen, dann sortierst du dieses nach dem Datum, und bringst dann nur die mit der Eigenschaft zur Anzeige die du benötigst.

Zeig am Besten mal in welchem Format deine Alarme vorliegen.
 
In deinem Screenshot ist aber nur ein Alarm-Objekt zu sehen, davon muss es ja mehrere geben. Die aktuelle Liste lässt sich doch bestimmt vom Server über eine Funktion abfragen. Vielleicht kannst du bei der Anfrage schon angeben, dass die die Liste sortiert oder sogar gefiltert haben möchtest.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Davon gibt es auch mehrere, momentan habe ich einpaar Testalarm Objekte im Atvise gemacht.
Unten findest du den Code für die Abfrage, denke das funktioniert soweit auch, es geht mir eigentlich nur um die richtige Ausgabe.
Denke dein Ansatz mit dem Array ist gut, aber weiss noch nicht genau wie ich die umsetzen soll.



Code:
var arrayAlarms = [];                                         // Array für die Zeilen  var filter = {};                                                 // Variable um das Objekt in der Konsole darzustellen 
 filter.address = ["g:AGENT.OBJECTS.*"];
 filter.type = [];
 

 	
 filter.type.push("v:2");			// alarm	
 filter.init = ["v:true"];    		// initial raw values for AGENT.OBJECTS.MyData.*
 

 webMI.data.subscribeFilter(filter, function(e) {
 var item = e;
 
Wollte so mal kurz testen ob der Array sich füllt, aber es wird immer einen 0 ausgeben.


Code:
console.log(item); 	if(item.state == 1 && item.ActiveStateId == true){
 	arrayAlarms = []
 	webMI.gfx.setText("txtAlarmDatum1", arrayAlarms.length)
 	}
 
Dazu müsste man sich die API-Beschreibung nochmal genau ansehen, was die für Funktionen bietet und wie die Alarme gemeldet werden.
Wenn die Funktion nach subscribeFilter immer bei einem neuen Alarm ausgeführt wird, würde ich alle Alarme oder zumindest die interessanten Daten in einem Array ablegen. Wenn diese schon in zeitlich geordneter Reihenfolge eintreffen, musst du die neuen Alarme nur hinten an dein Array anhängen. Gegangene müssen aus der Liste auch gelöscht werden. Ohne zu wissen wie du die Alarme hineinbekommst und was mit gegangenen passiert, ist das schwer von der Ferne zu sagen. Ich habe bei Atvise bisher immer das Standard-Alarm-Objekt verwendet, auch wenn das etwas "knusprig" aussieht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So wie es aussieht treffen diese in einer geordneten Reihenfolge ein.
Daher könnte man doch wie du gesagt hast, dies in ein Array geben,

Sehe ich das richtig wenn ich dies folgendermassen mache? So würde nach mir immer die neuste Meldung auf die [0] gesetzt im Array und die bestehenden Meldungen nach hinten verschoben?
Aber wie wird dan erkannt, welche nicht mehr aktiv sind?

Code:
if(item.state == 1 && item.ActiveStateId == true){ 	arrayAlarms.push
 
Danke für den Hinweis so funktionierts, leider bleibt das Objekt auch im Array enthalten wenn der Alarm nicht mehr aktiv ist.
Muss ich dies dem Array manuell wieder entziehen?
Wie es untensteht funktioniert es auf jedenfall nicht.


Code:
console.log(item); 	if(item.state == 1 && item.ActiveStateId == true){
 	arrayAlarms.push(item)
 	webMI.gfx.setText("txtAlarmDatum1", arrayAlarms.length)
 	}
 	else {
 	arrayAlarms.splice(item, 1)  
 	}
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mal angenommen die Alarm-ID identifiziert einen Alarm eindeutig. Dann könntest du bei einem Ereignis prüfen ob in deinem Array schon ein Alarm mit dieser ID vorhanden ist und diesen löschen. Oder du verwendest anstelle des Arrays ein Map-Objekt und als Key die Alarm-ID. Hat beides seine Vor- und Nachteile je nach Anwendungsfall.
 
Weiss nicht ob es die Prüfung benötigt, etwas speziell ist, das wenn ich nur die if-Anweisung habe das Array sauber hochzählt, ich kann dies dann auch ausgeben und die Anzeige wird, wenn ein Alarm dazukommt auch aktuallisiert, aber sobald ein Alarm wegfällt wird die Ausgabe erst aktuallisert wenn ich den Browser aktualisiert.
Wenn ich zwei mal den gleichen Alarm ausführe zählt das Array nicht weiter hoch.


Code:
console.log(item); 	if(item.state == 1 && item.ActiveStateId == true){
 	arrayAlarms.push(item)
 	webMI.gfx.setText("txtAlarmDatum2", arrayAlarms.length)
 		
 	}
 
Es müsste doch eine Funktion geben, um einmal eine Liste mit allen anstehenden Alarmen abzufragen, evtl. mit Filter auf "anstehende" falls das möglich ist. Dann könntest du mit der Abfrage die Liste neu füllen und müsstest dann gar nichts selber verwalten. Dann hast du aber etwas mehr Traffic auf dem Netzwerk. Schau dir doch mal an wie das Alarm-Objekt von Atvise das handhabt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Leider verstehe ich das Alarm handling von Ativse nicht ganz, daher hab ich mir erhofft das es auch so funktioniert, aber werde mich nochmals versuchen im verständnis des Code.

Code:
var alarmCount = 1; var strLenEventText = 24;
 var strLenAddress = 32;
 

 var alarmlistItems = [];
 var lng = "T{}";
 

 var minAlarmPriority = webMI.query["minAlarmPriority"];
 var maxAlarmPriority = webMI.query["maxAlarmPriority"];
 

 Date.prototype.to24String = function(_withMS) {
 	function _preNull(_nr) {
 		return _nr < 10 ? "0" + _nr : _nr;
 	}
 	if (this.getTime() < (new Date()).getTime() - 24*60*60*1000)
 		return this.getFullYear() + "-" + _preNull(this.getMonth()+1) + "-" + _preNull(this.getDate());
 	_ret = _preNull(this.getHours()) + ":" + _preNull(this.getMinutes()) + ":" + _preNull(this.getSeconds());
 	if (_withMS)
 		_ret += "." + this.getMilliseconds();
 	return _ret;
 };
 

 function cutString(str, maxLen, delimiter) {
 	str = "" + str;
 	maxLen = maxLen || 15;
 	delimiter = "" + delimiter;
 

 	if (str.length > maxLen) {
 		var strLenPart = (maxLen - delimiter.length) / 2;
 		var strLenPartBegin = Math.floor(strLenPart);
 		var strLenPartEnd = Math.ceil(strLenPart);
 

 		str = (str.substr(0, strLenPartBegin)) + delimiter + (str.substr(str.length - strLenPartEnd));
 	}
 

 	return str;
 }
 

 webMI.addOnload(function() {
     webMI.rootWindow.webMI.callExtension("SYSTEM.LIBRARY.ATVISE.QUICKDYNAMICS.Alarmmanagement", {"id": ""});
 	for (var i=0; i<alarmCount; i++) {
 		setEmpty(i);
 	}
 	webMI.trigger.fire("com.atvise.alarms_items", function(alarms){
 		for (var alarm in alarms){
 			var isAlarmNoLimits = (minAlarmPriority == 0 && minAlarmPriority == maxAlarmPriority);
 			var isAlarmInLimits = (minAlarmPriority < alarms[alarm].item.priority && alarms[alarm].item.priority < maxAlarmPriority);
 			if(isAlarmNoLimits || isAlarmInLimits){
 				setItem(alarms[alarm].item);
 			}
 		}
 	});
 	webMI.trigger.connect("com.atvise.alarms_notify_item", function(notify) {
 	    var e = JSON.parse(JSON.stringify(notify));
 	    var e = JSON.parse(JSON.stringify(notify));
 		if (e.value == false) {
 			alarmlistItems = [];
 			for (var i=0; i<alarmCount; i++)
 				setEmpty(i);
 		} else {
 			var isAlarmNoLimits = (minAlarmPriority == 0 && minAlarmPriority == maxAlarmPriority);
 			var isAlarmInLimits = (minAlarmPriority < e.value.priority && e.value.priority < maxAlarmPriority);
 			if(isAlarmNoLimits || isAlarmInLimits){
 				setItem(e.value);
 			}
 		}
 	});
 });
 

 function setEmpty(row) {
 	webMI.gfx.setText("row"+(row+1) + "_date", "");
 	webMI.gfx.setText("row"+(row+1) + "_msg", "");
 	webMI.gfx.setText("row"+(row+1) + "_adr", "");
 	webMI.gfx.setVisible("row"+(row+1)+"_alarm1_border", false);
 	var states = [1,2,3];
 	for (var i=0; i<states.length; i++)
 		webMI.gfx.setVisible("row"+(row+1)+"_alarm"+(i+1), false);
 }
 

 function formatString(obj, attribute){
 	var text = typeof obj[attribute] === "string" ? obj[attribute] : obj[attribute]["T{}"];
 	try {
 		return webMI.sprintf(text, obj, "T{}");
 	} catch (err) {
 		console.error(attribute+": " + text + "\n error: " + err);
 		return "";
 	}
 }
 

 // use buffer for rendering
 var buffer = [];
 var render = setInterval(renderLog, 250);
 

 webMI.addOnunload(function() {
 	clearInterval(render);
 	render = null;
 });
 

 function renderLog(){
 	var itm;
 	for(var i=0; i<alarmCount; i++)
 		if(itm = buffer.pop()) {
 			showItem(itm);
 		}
 	buffer = [];
 }
 

 webMI.addOnunload(function() {
 	clearInterval(render);
 	render = null;
 });
 

 function setItem(itm) {
 	itm.state = itm.state ? itm.state : "-1";
 	itm.timestamp = itm.timestamp ? itm.timestamp : "";
 	itm.address = itm.address ? itm.address : "";
 	itm.eventtext = itm.eventtext ? itm.eventtext : "";
 	buffer.push(itm);
 }
 

 function showItem(itm) {
 	itm.state = itm.state ? itm.state : "-1";
 	itm.timestamp = itm.timestamp ? itm.timestamp : "";
 	itm.address = itm.address ? itm.address : "";
 	itm.eventtext = itm.eventtext ? itm.eventtext : "";
 

 	if (itm.retain == false) return;
 

 	for (var i = 0; i < alarmlistItems.length; i++) {
 		if (alarmlistItems[i].address == itm.address && alarmlistItems[i].timestamp == itm.timestamp && alarmlistItems[i].state == itm.state) //unique alarm identifier
 			return;
 	}
 

 	if (itm.address != "") {
 		alarmlistItems.push(itm);
 		alarmlistItems.sort(function(a,b) { return a.timestamp - b.timestamp; });
 		alarmlistItems = alarmlistItems.slice((-1) * alarmCount);
 		alarmlistItems.sort(function(a,b) { return b.timestamp - a.timestamp; });
 	}
 

 	for (var i=0; i<alarmCount; i++) {
 		if (alarmlistItems[i] != undefined) {
 			setAlarm("row"+(i+1), alarmlistItems[i]);
 		} else {
 			setEmpty(i);
 		}
 	}
 

 	function setAlarm(row, item) {
 		if (item != undefined) {
 			var date = (new Date(item.timestamp)).to24String();
 			var eventtext = (item.eventtext ? formatString(item, "eventtext") : "");
 			webMI.gfx.setText(row + "_date", date);
 			webMI.gfx.setText(row + "_msg", eventtext ? cutString(eventtext, strLenEventText, "..") : "");
 			var dataItemAdress = item.address;
 			var replacedAdress = dataItemAdress.replace(/AGENT.OBJECTS./g,"");
 			webMI.gfx.setText(row + "_adr", cutString(replacedAdress, strLenAddress, ".."));
 			var state = item.state < 3 ? item.state : 3;
 			toggleSymbol(row, state);
 		} else {
 			toggleSymbol(row, -1);
 		}
 	}
 

 	function toggleSymbol(row, state) {
 		var states = [1,2,3];
 		for (var i=0; i<states.length; i++) {
 			var visible = (state == states[i] ? "inherit" : false);
 			webMI.gfx.setVisible(row + "_alarm"+(i+1), visible);
 			var active = (state == 1);
 			if (active) {
 				webMI.gfx.setVisible(row + "_alarm"+(i+1)+"_border", "inherit");
 			} else {
 				webMI.gfx.setVisible(row + "_alarm"+(i+1)+"_border", false);
 			}
 		}
 	}
 }
 
Wie kann ich ein Teil eines Objekt aus dem Array herausholen und ausgben?


Code:
webMI.gfx.setText("txtAlarmzeile2", arrayAlarms ["InputNode"]);
 
Zurück
Oben