# Javascript auf Webserver



## philipp00 (6 November 2020)

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.



```
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);
		}
	);
	}
```


----------



## Thomas_v2.1 (6 November 2020)

Und wie lautet die Frage, oder wo besteht das Problem? ;-)


----------



## philipp00 (6 November 2020)

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.


----------



## Thomas_v2.1 (6 November 2020)

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.


----------



## philipp00 (6 November 2020)

So werden sie in der Konsole dargestellt


----------



## Thomas_v2.1 (6 November 2020)

Das scheint aber nur ein Alarm-Objekt zu sein. Schau mal ob es eine Ebene darüber noch etwas gibt. Ist das Atvise?


----------



## philipp00 (6 November 2020)

jep das ist Atvise.
Benötige auch nur die Alarmobjekte, möchte nur dies anzeigen.


----------



## Thomas_v2.1 (6 November 2020)

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.


----------



## philipp00 (6 November 2020)

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. 




```
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;
```


----------



## philipp00 (6 November 2020)

Wollte so mal kurz testen ob der Array sich füllt, aber es wird immer einen 0 ausgeben.



```
console.log(item); 	if(item.state == 1 && item.ActiveStateId == true){
 	arrayAlarms = []
 	webMI.gfx.setText("txtAlarmDatum1", arrayAlarms.length)
 	}
```


----------



## Thomas_v2.1 (6 November 2020)

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.


----------



## philipp00 (6 November 2020)

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?


```
if(item.state == 1 && item.ActiveStateId == true){ 	arrayAlarms.push
```


----------



## Thomas_v2.1 (6 November 2020)

Füge die Alarme die du im Callback erhältst dem Array mit arrayAlarms.push(item) hinzu. Dann sollte die Liste immer länger werden.


----------



## philipp00 (6 November 2020)

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.



```
console.log(item); 	if(item.state == 1 && item.ActiveStateId == true){
 	arrayAlarms.push(item)
 	webMI.gfx.setText("txtAlarmDatum1", arrayAlarms.length)
 	}
 	else {
 	arrayAlarms.splice(item, 1)  
 	}
```


----------



## Thomas_v2.1 (6 November 2020)

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.


----------



## philipp00 (6 November 2020)

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.



```
console.log(item); 	if(item.state == 1 && item.ActiveStateId == true){
 	arrayAlarms.push(item)
 	webMI.gfx.setText("txtAlarmDatum2", arrayAlarms.length)
 		
 	}
```


----------



## Thomas_v2.1 (6 November 2020)

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.


----------



## philipp00 (6 November 2020)

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.


```
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);
 			}
 		}
 	}
 }
```


----------



## philipp00 (7 November 2020)

Wie kann ich ein Teil eines Objekt aus dem Array herausholen und ausgben?



```
webMI.gfx.setText("txtAlarmzeile2", arrayAlarms ["InputNode"]);
```


----------



## Thomas_v2.1 (7 November 2020)

arrayAlarms[0].InputNode für das erste Element des Arrays.


----------



## philipp00 (8 November 2020)

Danke das passt, dabei bin ich an mein nächsten Problem gekommen.
Sobald ich nicht nur das [0] Array auslese kommt die Fehlermeldung Array[1] undefined, aber die Ausgabe funktioniert.

Sie foto im Anhang, an was könnte das liegen? Evtl. an der Verarbeitung des Array?



```
console.log(item); 	if(item.state == 1 && item.ActiveStateId == true){
 	arrayAlarms.push(item)
 //	arrayAlarms.sort()
 

 		webMI.gfx.setText("txtAlarmDatum1", '08-11-2020');		
 		webMI.gfx.setText("txtAlarmbedinung1", arrayAlarms[0].InputNode);
 		webMI.gfx.setText("txtAlarmzeile1", arrayAlarms[0].eventtext.de);
 		webMI.gfx.setText("txtAlarmStatus1", arrayAlarms[0].ActiveState.de);		
 

 		webMI.gfx.setText("txtAlarmDatum2", '08-11-2020');		
 		webMI.gfx.setText("txtAlarmbedinung2", arrayAlarms[1].InputNode);
 		webMI.gfx.setText("txtAlarmzeile2", arrayAlarms[1].eventtext.de);
 		webMI.gfx.setText("txtAlarmStatus2", arrayAlarms[1].ActiveState.de);
```


----------



## Thomas_v2.1 (8 November 2020)

Du solltest die Länge des Arrays vorher abfragen, und dann z.B. in einer Schleife die Elemente durchgehen und zur Anzeige bringen.
Warum da trotzdem etwas ausgegeben wird kann ich nicht sagen, es sollte doch im Debugger sichtbar sein wie viele Elemente dein Array besitzt.


----------



## JSEngineering (8 November 2020)

Hallo,

warum nutzt Du nicht die fertigen Listen von atvise? Die besorgen das doch schon. Und über die Eigenschaften der Alarmliste sagst Du, was Du angezeigt haben möchtest.

Gruß
    Jens


----------



## JSEngineering (9 November 2020)

Hier noch ein Screenshot nachgereicht.
Das Alarmlog macht eigentlich das, was Du bauen möchtest. Falls es nicht ganz Deinen Ansprüchen genügt, kannst Du das zumindest als Vorlage nutzen, weil dort das Handling der Alarm-Items ersichtlich ist.

Gruß
   Jens


----------



## philipp00 (9 November 2020)

Hallo zusammen 

Ich weiss das es eine Vorlage gibt, leider verstehe ich nicht so ganz wie dies da gelösst wurde, daher dachte ich das ich es selber versuche, ist auch eine gute Übung im Umgang mit Javascript.
Anbei findet ihr den Stand, leider ist jetzt das Problem das sich nicht immer der neuste Alarm auf Pos 1 einreiht und dies sich auch nicht mehr aus dem Array löschen, ohne den Browser zu aktuallisieren.
Mir ist nicht ganz klar, wieso der Array nur bei aktualisierung des Browser neu initialisiert?




```
var arrayAlarms = []; 				// Alarmzeile
 var filter = {};
 

                                               
 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;
 

 console.log(item);
 	if(item.state == 1 && item.ActiveStateId == true){
 	arrayAlarms.push(item)
 	arrayAlarms.sort(arrayAlarms.timestamp)
 	var Alarmzahl = arrayAlarms.length
 	
 		if(Alarmzahl  >= 1){
 			webMI.gfx.setText("txtAlarmDatum1", '08-11-2020');		
 			webMI.gfx.setText("txtAlarmbedinung1", arrayAlarms[0].InputNode);
 			webMI.gfx.setText("txtAlarmzeile1", arrayAlarms[0].eventtext.de);
 			webMI.gfx.setText("txtAlarmStatus1", arrayAlarms[0].ActiveState.de);		
 		}
 

 		if(Alarmzahl >= 2){
 		
 			
 			webMI.gfx.setText("txtAlarmDatum2", '08-11-2020');		
 			webMI.gfx.setText("txtAlarmbedinung2", arrayAlarms[1].InputNode);
 			webMI.gfx.setText("txtAlarmzeile2", arrayAlarms[1].eventtext.de);
 			webMI.gfx.setText("txtAlarmStatus2", arrayAlarms[1].ActiveState.de);
 		}
 		
 		
 		if(Alarmzahl >= 3){
 			
 			webMI.gfx.setText("txtAlarmDatum3", '08-11-2020');		
 			webMI.gfx.setText("txtAlarmbedinung3", arrayAlarms[2].InputNode);
 			webMI.gfx.setText("txtAlarmzeile3", arrayAlarms[2].eventtext.de);
 			webMI.gfx.setText("txtAlarmStatus3", arrayAlarms[2].ActiveState.de);
 		}
```


----------



## Thomas_v2.1 (9 November 2020)

Du musst dich genauer in die Methoden der webMI Schnittstelle einlesen. Vermutlich musst du dich korrekt zum Empfang von neuen Alarmen anmelden, denn ich dem Code den du vom mitgelieferten Alarmobjekt gepostet hast, werden da diverse andere Dinge angestellt. Ich vermute mal, beim ersten Aufruf oder nach Verbindungsabbruch werden alle Alarme gelesen, und anschließend nur noch die Änderungen abonniert. Mit herumprobieren kommst du aber nicht weit, Dokumentation lesen, ein Konzept erarbeiten und es dann programmieren. Oder du verwendest das Fertige und bist zufrieden damit.

Und du willst doch nicht wirklich jede Alarmzeile so auscodieren wie oben?
Dafür gibt es for-Schleifen, wie


```
for (i = 0; i < arrayAlarms.length; i+) {
  webMI.gfx.setText("txtAlarmzeile" + (i-1), arrayAlarms[i].eventtext.de);
...
```


----------



## JSEngineering (9 November 2020)

Hallo Philipp,

ich würde auch sagen: Vorlage verstehen und Doku lesen.
Das Thema dieser Alarmliste ist entsprechend komplex und nicht geeignet, das selbst ohne tiefe Kenntnisse zu erstellen.
Wenn Du die Vorlage verstehst, ist das bereits eine sehr gute Übung und danach kannst Du sie anpassen.

Tipp: Von library/atvise in library/project kopieren und darin arbeiten: Du behältst das Original und Deine geänderte Version wird auch nicht von einem Update überschrieben...

Gruß
    Jens


----------



## philipp00 (11 November 2020)

Dann werde ich mich mal versuchen den bstehenden Code zu verstehen, evtl. könnt ihr mir da etwas helfen.
Soweit  ich das verstehe ist die Funktion setAlarm zuständig die Objekt  auszulsen die über den Webserver ausgegeben werden, da ich noch einen  weitere Spalte mit der Status informaiton anzeigen möchte muss ich  zuerst diese hier auslesen, leider hat das noch nicht so gut geklappt.

Habe diesen Code Teil herauskompiert und einen Printscreen beigefügt mit dem Teil der ausgelesen werden soll.
In  den Kommentaren habe ich versucht meine überlegung aufzuschreiben,  sprich wie ich es verstehe und rot markiert ist der Teil den ich noch  nicht ganz verstehen.




```
for (var i=0; i<alarmCount; i++) {                                                         // for Schleife,  die Variable alarmCount habe ich auf 3 gesetzt, sprich die Schleife wird  nur ausgeführt wenn i kleiner 3 ist
       if (alarmlistItems[i] !=  undefined) {                                               // Die  Anweisung wird nur ausgeführt wenn diese Array belegt ist.
             setAlarm("row"+(i+1), alarmlistItems[i]);                                  // rowx und der Wert aus dem array alarmlistitems, werden in den setAlarm eingefügt 
       } else {
              setEmpty(i);                                                                        //der i Wert wird in die Variable setEmpty geschrieben
       }
}
 

     function setAlarm(row, item)  {                                                                                                                // Alarm in den Objekten abrufen
         if (item != undefined)  {                                                                                                                      // Wenn die Variable item defniert ist wird die Anweisung ausgeführt
             var date = (new  Date(item.timestamp)).to24String();                                                                          // Hier wird der Zeitstempel ausgelesen und mit to24String umgerechnet 
[COLOR=#ff0000]             var eventtext =  (item.eventtext ? formatString(item, "eventtext") :  "");                                                // Auslesen der  Alarmbedigung, nur verstehe ich das vorgehen hier nicht ganz [/COLOR]
             webMI.gfx.setText(row + "_date",  date);                                                                                          // Ausgabe des Zeitstempel
[I][COLOR=#ff0000]           webMI.gfx.setText(row  + "_msg", eventtext ? cutString(eventtext, strLenEventText, "..") :  "");                 // Ausgabe der Alarmbedigung[/COLOR]
[COLOR=#ff0000]             // webMI.gfx.setText(row +  "_st" ,  ActiveState);                                                                               // Hier wollte ich den Status ausgeben[/COLOR] [/I]  
[COLOR=#ff0000]             var dataItemAdress =  item.address;                                                                                                //  Was bedeutet item.address[/COLOR]
[COLOR=#ff0000]             var replacedAdress =  dataItemAdress.replace(/AGENT.OBJECTS./g,"");                                                   // 
             webMI.gfx.setText(row + "_adr", cutString(replacedAdress, strLenAddress, ".."));                                    //
             var state = item.state < 4 ? item.state :  4;                                                                                      //
             toggleSymbol(row,  state);                                                                                                             //[/COLOR]
         } else {
             toggleSymbol(row,  -1);                                                                                                                 //
         }
     }
```


----------



## JSEngineering (12 November 2020)

Hallo Philipp,

zu Deinen Fragen:


Vermutlich beziehst Du Dich auf das Konstrukt (... ? ... : ...): Das lautet so (Bedingung)?(Befehl bei True)Befehl bei False). Damit machst Du kurz und knapp eine bedingte Zuweisung. Beispiel: var ZahlGroesserEins = (Zahl > 1) ? true : false; - Im Endeffekt prüfen sie, ob der Eventtext definiert ist. Weil falls undefiniert, würde das Script mit Fehler abbrechen.
Bezüglich der ItemAddress: Das ist meine ich die auslösende Variable. Ich meine mich zu erinnern, daß webMI über die Variablenadresse die Quittierung durchführt, über die AlarmID macht atvise SCADA das. Daher sind beide Quittierungsmethoden im Template hinterlegt und es müssen daher auch beide Informationen im Alarmobjekt hinterlegt werden.

Falls das nicht weiter hilft, bitte die Fragen konkreter stellen 

Gruß
    Jens


----------



## philipp00 (12 November 2020)

Danke für dein Feedback, war schon mal sehr hilfreich für das verständnis.
Nun hab ich mich versucht in der Erweiterung des Code (siehe rote Zeile im Code), ich möchte das der Status (Aktvie/Inaktiv) angezeigt wird.
Habe mich an der Ausgabe von Eventtext gehalten, aber aus irgend einem Grund erfolgt die Ausgabe nicht, sprich die Variable (activestate) wird nicht beschrieben.
Sieht jemand den Fehler?






```
function setAlarm(row, item) {																		// Alarm in den Objekten abrufen 		if (item != undefined) {

function setAlarm(row, item) {																		// Alarm in den Objekten abrufen 		if (item != undefined) {
 			var date = (new Date(item.timestamp)).to24String();
 			var eventtext = (item.eventtext.de ? 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, ".."));

 			[COLOR=#ff0000]var activestate = (item.ActiveState ? formatString(item, "ActiveState") : "");			[/COLOR]

 			[COLOR=#ff0000]webMI.gfx.setText(row + "_st" , activestate ? cutString(activestate, strLenActiveSate, "..") : "");		[/COLOR]
```


----------



## JSEngineering (12 November 2020)

Spontan würde ich sagen, Dir fehlt noch eine Ebene im Objektzugriff: Die Entscheidung ob Du die Anzeige deutsch (.de) oder englisch (.en) haben willst. ActiveState an sich ist ja noch kein String, sondern ein Objekt.


----------



## philipp00 (12 November 2020)

Das habe ich auch schon ausprobiert, leider hat dies irgendwie nicht funktioniert, sprich es wurde einen Fehlermeldung in der Konsole ausgegeben.
Daher habe ich gedacht es funktioniert auch so, da es beim eventtext auch funktioniert.



```
[COLOR=#ff0000]var activestate = (item.ActiveState.de ? formatString(item, "ActiveState") : "") [/COLOR]/CODE]
```


----------



## JSEngineering (13 November 2020)

Wenn ich das aber richtig sehe, fragst Du bei item.eventtext aber *.de* in der Bedingung ab. Bei item.ActiveState aber keine Sprache. Dadurch springt er ggf. direkt in die FALSE-Anweisung.

Ansonsten guck Dir bitte mal die Funktion formatString im Code an:


```
function formatString(obj, attribute) { 	var text = typeof obj[attribute] === "string" ? obj[attribute] : obj[attribute]["T{}"];

 	try {

 		return webMI.sprintf(text, obj);

 	} catch (err) {

 		console.error(attribute+": " + text + "\n error: " + err);

 		return "";

 	}

 }
```

Demnach wird ein Fehler in der Console ausgegeben, wenn die Funktion nicht klappt. Es hilft auch immer, die Funktionen console.log, console.warn und console.error selbst zu nutzen, um sich selbst Ausgaben zu machen. Wenn Du die Variable direkt in der Ausgabe angibst, wird auch ggf. das aufklappbare Objekt angezeigt.


----------



## philipp00 (13 November 2020)

Stimmt, aber die Funktion bleibt die gleiche wenn der Eventtext ohne .de abgefragt wird.
Speziell ist nur etwas, dass der activestate sich ansonsten (in meinem alten Code) so auslesen.


----------



## JSEngineering (13 November 2020)

Hab leider gerade kein Projekt am Laufen.
Mußt Du mal bitte in der Browser-Console weiter untersuchen. Google Chrome hat hier viele Werkzeuge zum debuggen...


----------

