Javascript auf Webserver

Zuviel Werbung?
-> Hier kostenlos registrieren
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?


Code:
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);



Alarmfenster im Browser.JPGArray_undefined.JPG
 
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.
 
atvise-Bibliothek.jpg

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
 
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?



Code:
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);
 		}
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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

Code:
for (i = 0; i < arrayAlarms.length; i+) {
  webMI.gfx.setText("txtAlarmzeile" + (i-1), arrayAlarms[i].eventtext.de);
...
 
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
 
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.



Code:
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);                                                                                                                 //
         }
     }



Alarmstatus.JPG
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Philipp,

zu Deinen Fragen:

  1. 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.
  2. 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 :D

Gruß
Jens
 
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?





Code:
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]


Activestat.JPG
 
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.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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.


Code:
[COLOR=#ff0000]var activestate = (item.ActiveState.de ? formatString(item, "ActiveState") : "") [/COLOR]/CODE]
 
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:

Code:
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.
 
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.
 
Zurück
Oben