WinCC Unified Faceplate - EA-Feld dynamisieren

Mauser89

Level-2
Beiträge
56
Reaktionspunkte
5
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin,

ich arbeite zur Zeit an Bildbausteinen und möchte ein einfaches EA-Feld im Bildbaustein selber mit einem UDT verbinden.
Gleichzeitig habe ich unter den Schnittstelleneigenschaft eine boolsche Variable angelegt und hier ist die Frage, wie ich mit einer einfachen If Anweisung die Eigenschaft ansprechen kann?
1775814323124.png

Dazu habe ich das EA-Feld

mit dem Code
1775814386402.png

versehen.

Der Code stammt aus der KI, da mein eigener nicht funktioniert hat, obwohl bei der Übersetzung keine Fehler angezeigt wurden.
"
let value = item.ProcessValue;

// 1. Zugriff auf die Boolean-Eigenschaft
if (MinAlarm) {
Tags("UDTSensor.Alarmgrenzen.Soll_Min Alarm").Write(value);

}

return value;

"

Am Ende möchte ich im aufgerufenen Faceplate nur
1775814732831.png
den Haken an der entsprechenden Stelle setzen, um den eingegebenen Wert den vier Alarmgrenzen zuzuweisen.

Zum Verständnis:
export function EA_Feld_7_ProcessValue_Trigger(item, triggerDataSet) {

sind die der Funktion übergebenen Parameter. Item = EA Variable? Trigger = Wie wird das Script getriggert?

der Returnwert steht dann im EA-Feld?

Danke für eure Hilfe
 

Anhänge

  • 1775814814086.png
    1775814814086.png
    12,9 KB · Aufrufe: 7
Hi, ich bin selber noch am JS lernen, als hier meine Antwort auf die Gefahr hin, dass alles absoluter Blödsinn ist:
1. In einer Exportfunction wird der Rückgabewert nicht mit "let" definiert sondern direkt "var" verwendet.
2. Du greifst auf zwei Globale Variablen zu, daher musst du den Zugriff mit read() ausführen.
3. Du brauchst einen Rückgabewert
4. Eine IF-Anweisung sollte auch immer ein "ELSE" beinhalten

Generell macht KI hier viel Blödsinn, da sie die Aufrufumgebung WinCC unified nicht wirklich berücksichtigt. Leider hab ich aktuell keine Testumgebung zur Hand, um dir einen vernünftigen Bsp. Code zu geben
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Code stammt aus der KI, da mein eigener nicht funktioniert hat, obwohl bei der Übersetzung keine Fehler angezeigt wurden.
Der Code-Editor ist sehr...fehlertolerant.
Wenn dein Code syntaktisch Sinn ergeben könnte, wird er nicht angemeckert.
Es wird aber nicht geprüft ob die Variablen, Methoden oder Properties überhaupt existieren.

KI uns Siemens ist mit äußerster Vorsicht zu genießen, da das große S in vielen Punkten etwas speziell ist & sich in Details anders als eine normale JS-Umgebung verhält.
Ohne JS-Connector macht KI in Unfied nur sehr bregrenz Sinn & auch nur wenn man wirklich weiß was man tut um zu verstehen ob der Output funktionieren kann.

1. In einer Exportfunction wird der Rückgabewert nicht mit "let" definiert sondern direkt "var" verwendet.
Let & var unterscheiden sich nur im Scope der erzeugten Variable.
Ist an dieser Stelle irrelevant.
Ich hab noch keine Situation gehabt, in der ich var gebraucht hätte.

2. Du greifst auf zwei Globale Variablen zu, daher musst du den Zugriff mit read() ausführen.
Ich weiß zwar nicht wo du eine globale Variable siehst, aber auf die Schnittstellenvariable musst du tatsächlich per Tag-Objekt zugreifen.

3. Du brauchst einen Rückgabewert
In diesem Fall aber nur, weil der Rückgabewert bei der Scriptdynamisierung der jeweiligen Property zugewiesen wird.

4. Eine IF-Anweisung sollte auch immer ein "ELSE" beinhalten
Blöde Frage: warum?

Am Ende möchte ich im aufgerufenen Faceplate nur
1775814732831.png

den Haken an der entsprechenden Stelle setzen, um den eingegebenen Wert den vier Alarmgrenzen zuzuweisen.
sind die der Funktion übergebenen Parameter. Item = EA Variable? Trigger = Wie wird das Script getriggert?

der Returnwert steht dann im EA-Feld?
Ok, kapier ich nicht ganz....
Du willst aus dem UDT eine Bool-Variable lesen & je nach Zustand eine Property auf der Faceplate-Schnittstelle umschalten?
Und wann soll was genau passieren?
Bitte einmal Erklärung für ganz begriffsstutzige (っ °Д °;)

Und fürs Protokoll:
 
Frueher vor 25 Jahren konnte man mit Intouch ein paar Objekte zu einem Objekt gruppieren.
Hatte ich jetzt eine Variablenpool der zum Bsp. einen Motor betraf konnte man die Variablen alle Anzeigen lassen.

Man konnte dann Motor 1 kopieren und aus 1 eine 2 machen und das wars.Was ist das anderes als eine Faceplate?
Das war eine Sache von ein paar Minuten.Oder verstehe ich das Ganze noch nicht?
 
Nach dem wir jetzt eh schon über KI diskutieren, hab ich das zum Anlass genommen und die Frage dem Siemens-Industrial Copilot gestellt (Pilot Version). Ich hab einen lauffähigen Code bekommen und dann eine Testumgebung gebaut. Bei mir funktioniert es.
Erklärung Runtime Bild: links ist der Haken bei MinAlarm gesetzt --> er schreibt den Startwert aus meinem DB ("2,2"), rechts ist der Haken nicht gesetzt --> er schreibt 0, weil kein Alarm Min wert genutzt wird. Das weiter EA_Feld ist eine direkte Darstellung ohne Faceplate zum testen (nur für mich notwendig).

Javascript:
export function EA_Feld_1_ProcessValue_Trigger(item, triggerDataSet) {
    let minAlarm = Faceplate.Properties.MinAlarm;  
     
    if (minAlarm == true) {
        return Tags("UDTSensor.Alarmgrenzen.Soll_Min_Warnung").Read();
    }
    return 0;
}


code.pngKI.pngruntime.png
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Erstmal danke für eure Antworten.

Ich habe das Problem jetzt so lösen können:
export function EA_Feld_7_ProcessValue_Trigger(item, triggerDataSet) {

let Eingabe = parseFloat(item.ProcessValue);

if (Faceplate.Properties.MinAlarm === true) {
Tags("UDTSensor.Alarmgrenzen.Soll_Min Alarm").Write(Eingabe);
return Eingabe;
}
if (Faceplate.Properties.MinWarnung === true) {
Tags("UDTSensor.Alarmgrenzen.Soll_Min Warnung").Write(Eingabe);
return Eingabe;
}
if (Faceplate.Properties.MaxWarnung === true) {
Tags("UDTSensor.Alarmgrenzen.Soll_Max Warnung").Write(Eingabe);
return Eingabe;
}
if (Faceplate.Properties.MaxWarnung === true) {
Tags("UDTSensor.Alarmgrenzen.Soll_Max Alarm").Write(Eingabe);
return Eingabe;
}
else 0

}

Funktionsbeschreibung:

- UDT in der SPS der HH, H, L und LL Grenzen verarbeitet
- Wird im Faceplate genutzt
- Die Bedinungen der IF-Anweisungen beinhalten eine Eigenschaftsschnittstelle, in der man dann später nur einen Haken setzen muss, welcher Alarm es sein soll

Ich habe wirklich viel hin und her probiert. Der Vergleichsoperator == hat bei mir nicht funktioniert.

Das Faceplate werde ich trotzdem nciht benutzen, da das HMI ständig den Wert im DB überschreibt. Eine Änderung vom DB aus ist damit nicht mehr möglich. Letztenendes habe ich 4 Faceplates für die Alarmgrenzen erstellt.

Zusammenfassend:

if (Faceplate.Properties.MinAlarm === true)

MinAlarm = Eigenschaftsschnittstelle
, 1:1 der Name. Da kann man jeden Müll hinschreiben, der Editor meckert nicht!!!! Das macht mich Wahnsinnig.

=== TRUE fragt neben dem Ergebnis von TRUE or FALSE auch den Datentyp mit ab.

Diese Befehl wird im Faceplate ausgeführt. Ich denke wenn man außerhalb eines FP ist, müsste man Parent.Faceplate oder sowas nutzen.
Bei unserem Siemens ist die Unterstützung gering, leider. Ich vermisse eine "Formelsammlung" wo einfach jeder Befehl ohne große Beschreibung drauf steht. Für JS gibt es das überall im Internet, nur für Siemens finde ich nichts. Aber bei Siemens habe ich noch nie was gefunden :D Also Siemens geht mir aktuell richtig auf den Sack.
 
Frueher vor 25 Jahren konnte man mit Intouch ein paar Objekte zu einem Objekt gruppieren.
Hatte ich jetzt eine Variablenpool der zum Bsp. einen Motor betraf konnte man die Variablen alle Anzeigen lassen.

Man konnte dann Motor 1 kopieren und aus 1 eine 2 machen und das wars.Was ist das anderes als eine Faceplate?
Das war eine Sache von ein paar Minuten.Oder verstehe ich das Ganze noch nicht?
Früher gab es auch noch Simatic Manager, katastrophe für mich :D

Also mit den alten Sachen kenne ich mich nicht aus.

Ein Faceplate wird m.E. optimalerweise mit einem UDT aus der SPS bedient. Ich habe jetzt bspw. ein Faceplate erstellt mit 20 Variablen, aber da es jetzt ein UDT ist, muss ich nur noch eine Variable drauf ziehen. Das macht die Fehleranzahl kleiner und man ist schneller fertig. Coole Sache.
 
Nach dem wir jetzt eh schon über KI diskutieren, hab ich das zum Anlass genommen und die Frage dem Siemens-Industrial Copilot gestellt (Pilot Version). Ich hab einen lauffähigen Code bekommen und dann eine Testumgebung gebaut. Bei mir funktioniert es.
Erklärung Runtime Bild: links ist der Haken bei MinAlarm gesetzt --> er schreibt den Startwert aus meinem DB ("2,2"), rechts ist der Haken nicht gesetzt --> er schreibt 0, weil kein Alarm Min wert genutzt wird. Das weiter EA_Feld ist eine direkte Darstellung ohne Faceplate zum testen (nur für mich notwendig).

Javascript:
export function EA_Feld_1_ProcessValue_Trigger(item, triggerDataSet) {
    let minAlarm = Faceplate.Properties.MinAlarm; 
    
    if (minAlarm == true) {
        return Tags("UDTSensor.Alarmgrenzen.Soll_Min_Warnung").Read();
    }
    return 0;
}


Anhang anzeigen 95554Anhang anzeigen 95555Anhang anzeigen 95556
Hey,

danke für den Tipp! Habe bislang nur Grok und den normalen Copilot genutzt. Ich habe meine Lösung oben gepostet. Komischerweise hat er bei mir mit == nicht gearbeitet.

Vielen Dank für deine Mühe!
 
Ich habe auch Faceplates, in denen ich EA-Felder dynamisch beschalte.

Ich habe 3 Felder und je nach Wert der Variable "unit" wird das Zeitformat angepasst, also z.B. hh:mm:ss oder ss:mm usw.

Hier ist eines der Felder. Je nach Einheit wird "type_timer.set_time.values.ms/s/m/h" als String zusammengebastelt und der String per return zurückgegeben.
Das Skript liegt direkt auf dem EA-Feld/Prozesswert.
Javascript:
// 1. Wert der Einheit lesen
let unit = Tags("type_timer.set_time.unit").Read();

// 2. Basis-Pfad zu den Werten
let path = "type_timer.set_time.values.";
let tagName = "";

// 3. Zuordnung der Zeiteinheit
switch (unit) {
    case 0: case 4:
        tagName = "ms"; break;
    case 1: case 5:
        tagName = "s"; break;
    case 2: case 6:
        tagName = "m"; break;
    case 3:
        tagName = "h"; break;
    case 7:
        tagName = "s"; break;
    default:
        return 0; // Fallback
    }

// 4. Den Wert der dynamischen Variable zurückgeben
return Tags(path + tagName).Read();

Zur Info:
Ich habe meinen JavaScript Code fast ausschließlich mit Gemini geschrieben, aber nie hat der erste Entwurf funktioniert, da das Scripting viele Stolpersteine bietet. Mit dem TraceViewer konnte man dann aber oft sehen, warum etwas nicht funktioniert.
Mittlerweile habe ich in Gemini viele Regeln hinterlegt, um diese Eigenheiten abzufangen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wofür gibt es dann JS bzw. die Dynamisierung?
Nur weil es was gibt, heisst es noch lange nicht dass es der beste Weg ist.
Ich bin der Meinung das Siemens mit Java Script vieles verkompliziert hat.
Das meisste was ich visualisierungstechnisch hier sehe konnte man vor 25 Jahren mit Intouch machen.Nur viel leichter.
Und ich bin kein Visualisierungsexperte.
UDT's gab es frueher schon.Mit Intouch konnte man ein Objekt gruppieren und hat dann mit rechtem MausklicK die Schnittelle aller Objektvariablen gesehen.Dann hat man die UDT Variable ersetzt pro gruppiertem Objekt.Wenn ich jetzt nicht gerade 100 Objekte hatte mit 20 Variablen ging das sehr schnell.
 
Zurück
Oben