WinCC Unified JavaScript - blutiger Anfänger hat Syntaxfragen

Ludewig

Level-3
Beiträge
1.170
Reaktionspunkte
254
Zuviel Werbung?
-> Hier kostenlos registrieren
Ziel: Abfrage, ob dem aktuell angemeldeten Benutzer die Rolle "HMI Operator" zugeordnet ist. Die HMI-Variable "Operator_logged_in" soll dann auf TRUE gesetzt werden.
Im Aufgabenplaner wurde dieses Skript mit Hilfe eines Snippets angelegt und testhalber im 10-Sekunden-Takt ausgelöst:

Anmerkung: Nachstehender Screenshot enthält Darstellungsfehler durch RDP-Zugriff auf VM im Bürorechner.

1767208232742.png
Wenn ich einen User anmelde, der "HMI Operator" ist, wird seine Rolle jedoch nicht erkannt. Tausche ich True und False, wirde der zweite Befehl korrekt ausgeführt.
Auch kommt die Trace-Ausgabe, wie zu erwarten, immer aus dem else-Zweig.

Mit einem anderen Snippet versuchte ich deshalb, die dem Benutzer zugeteilten Rollen auszulesen:

Code:
export function Task_Aufgabe_3_Update()
let roles = HMIRuntime.UserManagement.GetRolesFromUser();
if(roles.length > 0){
  let strRoles = '';
  roles.forEach((roleName) => {
    strRoles += roleName + ';';
  });
  HMIRuntime.Trace("The current user is in role(s): " + strRoles);
}
else{
  HMIRuntime.Trace("User has no roles.");
}

}
Es wird keine einzige Rolle erkannt.

Umgebung = TiaV20 + 12"-MTP
Wo könnten die Fehler liegen?
 
Wenn ich einen User anmelde, der "HMI Operator" ist, wird seine Rolle jedoch nicht erkannt. Tausche ich True und False, wirde der zweite Befehl korrekt ausgeführt.
Auch kommt die Trace-Ausgabe, wie zu erwarten, immer aus dem else-Zweig.
Ist nur der Screenshot mies oder steht da "tag1.Writc(truc)"?
Dann wäre das eine Spende für das "try..Catch & Trace"-Kässchen (⁠~⁠ ̄⁠³⁠ ̄⁠)⁠~
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
@Ludewig :
bei dem geposteten Code-Snippet (Task_Aufgabe_3_Update) fehlt am Anfang schon mal die geschweifte Klammer.
Die Syntax ansich kann ich nicht checken weil ich das Spiel Unified nicht mehr mitspiele.
Ganz genrell empfehle ich aber bei JavaScript (oder auch C#) ganz strickt mit den Einrückungen zu arbeiten - das erhöht zum Einen die Übersichtlichkeit und zum Anderen sieht man schneller ob etwas fehlt oder komplett abgeschlossen ist ... UND .. man sieht viel besser was zusammen gehört.
 
Ganz genrell empfehle ich aber bei JavaScript (oder auch C#) ganz strickt mit den Einrückungen zu arbeiten - das erhöht zum Einen die Übersichtlichkeit und zum Anderen sieht man schneller ob etwas fehlt oder komplett abgeschlossen ist ... UND .. man sieht viel besser was zusammen gehört.
+1
Da der TIA Editor noch keine Auto Formatierung beherrscht verwende ich dafür beispielsweise Notepad++ mit dem JSTools-Plugin oder VSCode.
Damit siehst du dann auch Recht schnell ob irgendwo eine Klammer fehlt oder zu viel ist.
 
Ich habe jetzt einen anderen Weg gewählt, um die Daten aus der VM ins Netz zu hieven:

Code:
export function Task_Aufgabe_2_Update() {
let roleName = "HMI Operator";
let retVal = HMIRuntime.UserManagement.HasUserRole(roleName);
if(retVal){
  HMIRuntime.Trace("The current user is in role: " + roleName);
let tag1 = Tags("Operator_logged_in");
tag1.Write(true);
}
else{
  HMIRuntime.Trace("The current user isn't in role: " + roleName);
let tag1 = Tags("Operator_logged_in");
tag1.Write(false);
}
}

und
Code:
export async function Task_Aufgabe_3_Update() {
let roles = HMIRuntime.UserManagement.GetRolesFromUser();
if(roles.length > 0){
  let strRoles = '';
  roles.forEach((roleName) => {
    strRoles += roleName + ';';
  });
  HMIRuntime.Trace("The current user is in role(s): " + strRoles);
}
else{
  HMIRuntime.Trace("User has no roles.");
}
}

Notepad++ habe ich jetzt mal runtergeladen. Aber trace sagt mit nicht, dass der Code Probleme mache.
Es sieht einfach so aus, als liefen die Methoden(?)
HMIRuntime.UserManagement.HasUserRole(roleName)
und
HMIRuntime.UserManagement.GetRolesFromUser()
ins Leere.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Aber trace sagt mit nicht, dass der Code Probleme mache.
Deswegen try..Catch & Trace.
Erklärung & Beispiel siehe hier bzw. im Rest des Threads.
Schau dir auch bitte mal diesen Beitrag an, da stehen solche Sachen auch mit drin.

Ich sollte wirklich mal nen Post mit den absoluten Standard-Dingen im Unified Scripting erstellen....

Es sieht einfach so aus, als liefen die Methoden(?)
HMIRuntime.UserManagement.HasUserRole(roleName)
und
HMIRuntime.UserManagement.GetRolesFromUser()
ins Leere.
Das tun sie vermutlich nicht.
Hab das selbst schon verwendet, diese Methoden funktionieren (korrekt angewendet) einwandfrei.
Welche Trace-Ausgaben bekommst du konkret?
Keinen Trace oder die Negativ Rückmeldung aus dem jeweiligen Else Zweig?
 
Die Trace-Ausgaben waren in beiden Fällen die else-Zweige. Mit Skript-Filter bekam ich keine Fehlermeldungen.
Leider gibt es aktuell Zugriffsprobleme. Da ich 1200 km vom System entfernt bin, muss ich erst jemanden finden, der einen harten Neustart auslöst.
Erst mal Danke für Deine Reaktion.
 
Mittlerweile ist das MTP mittels Hardware-Reset und Prosave wiederhergestellt. Ich kann also weiterarbieten:

Eingeloggt ist hier der User "Werkstatt", dem mehrere Rollen zugebilligt wurden.
Dazu 2 Screenshots des Trace-Viewers:
1767707947508.png
und

1767707974419.png

Hinweis: Die Nummer der Taskplaner-Aufgabe weicht hier vom Code weiter oben ab, sonst ist der identisch.

Ich denke, der Code ist syntaktisch okay, da er mit dem jeweiligen Snippet übereinstimmt. Wie könnte man weiter vorgehen?
Gibt es da ein Kontextproblem?
 
Sind die Methoden vlt. asynchron und geben einen promise zurück?
Nope, sind synchrone Funktionen.
Er benutzt auch die Code-Schnipsel aus der F1-Hilfe, die sollten auf jeden Fall funktionieren.
Da ist irgendwas anderes Faul...

Eingeloggt ist hier der User "Werkstatt", dem mehrere Rollen zugebilligt wurden.
Stimmt die Schreibweise von "HMI Operator" exakt mit der dem Benutzer zugewiesenen Rolle überein?
Kannst du dem User mal nur eine Rolle zuweisen?
Auch wenn du einem User mehrere Rollen zuweisen kannst, verwendet dieser nur die Rolle mit den niedrigsten Rechten.
Ggf. kann das lustige Konflikte verursachen...
Gibt es da ein Kontextproblem?
Wo genau rufst du denn die Scripte auf?
 
  • Die Rolle HMI Operator ist der Standard-Eintrag im Snippet, so dass ich gar nichts verändern mussste.
  • Habe den User Heinz angelegt, der nur HMI Operator ist -> keine Veränderung.
  • Ich rufe beide Skripte testhalber synchron im 10-Sekunden-Takt im Aufgabenplaner auf.
1767814815701.png
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich rufe beide Skripte testhalber synchron im 10-Sekunden-Takt im Aufgabenplaner auf.
Aaand there it is 💩
Der Benutzer ist eine clientseitige Eigenschaft, während der Aufgabenplaner im Serverkontext läuft.
Ich bin eher überrascht, dass der Editor hier überhaupt den Aufruf einer UserManagement-Methode zulässt.
Zugriff auf UI im Aufgabenplaner führt beispielsweise direkt zu einem Syntaxfehler.

Als Lösung musst du die Abfrage der Rollen im UI-Kontext ausführen.
Dazu kannst du beispielsweise im Aufgebaut-Ereignis deines Hauptbildes eine Subscription auf "@UserName" erstellen und den Code in deren Callback-Funktion aufrufen.
Alternativ könntest du den aktuell angemeldeten Benutzer in einem dauerhaft geladenen EA-Feld anzeigen & über dessen ValueChange-Ereignis arbeiten.
Bei mir sieht das beispielsweise so aus:
1767852245069.png
Als Prozesswert des EA-Felds ist "@UserName" parametriert + der entsprechende Code angehängt.
In meinem Fall schreibt der Code die Rollen in die Textbox unterhalb des EA-Felds.
1767852337345.png
 
Okay, es geht also beim Lernen mit dem Thema Kontext weiter. Heute und morgen habe ich Reisetage. Am Wochenende geht es weiter.
Danke für Deinen Einsatz.
 
Ich sollte wirklich mal nen Post mit den absoluten Standard-Dingen im Unified Scripting erstellen....
Ja, würde mich freuen! Bisher konnte ich mir mit einer Kombination aus Beispielen, diesem Forum und viel Probieren immer zum Ziel kommen, aber meine Glaskugel sagt mir, dass es a) besser gehen muss und b) in Zukunft eher mehr als weniger JS Anteil in meinen Visus von Nöten sein wird...
 
@Botimperator weißt du zufällig, ob es einen Weg gibt, auch auf die rechte einer zuzugreifen?
Ich fürchte da muss ich passen.
Das HMIUserManagement-Objekt hat (Stand V21) nur die beiden rollenbezogenen Methoden & keine weiteren Properties.
Also ist der Punkt an die Rechte der Rollen ran zu kommen zumindest von der Script-Seite bzw. der lokalen Benutzerverwaltung meines Wissens nach nicht möglich.

Evtl. Gibt's eine Möglichkeit über den UMC-Dienst & die zentrale Benutzerverwaltung an die Zuordnung der Rechte & Rollen zu kommen.
Mit dem habe ich mich allerdings bisher noch nicht näher befasst.
 
Schade. Trotzdem danke.
Hintergrund des ganzen ist, dass ich in einem Faceplate einen Button habe, der allerdings transparent ist. Ich hätte das Faceplate gerne ausgegraut (wie bei ein Button) wenn der Benutzer das entsprechende Recht nicht besitzt.
Im Prinzip ist es nur ein Schönheitsfehler..🤷
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Schade. Trotzdem danke.
Hintergrund des ganzen ist, dass ich in einem Faceplate einen Button habe, der allerdings transparent ist. Ich hätte das Faceplate gerne ausgegraut (wie bei ein Button) wenn der Benutzer das entsprechende Recht nicht besitzt.
Im Prinzip ist es nur ein Schönheitsfehler..🤷
Achso, da kann ich dir weiterhelfen :D
Die meisten ScreenItems haben die Methode "CheckAuthorization()".
Damit kannst du prüfen ob der aktuell angemeldete Benutzer das Recht besitzt das Item zu bedienen.
Gibt zwar nur ein true/false, sollte aber für deinen Zweck genau das Richtige sein.

Code-Beispiel aus einem meiner Faceplates:
Javascript:
    try {
        //Überwachung auf Benutzerwechsel starten
        let subsTo_SystemUsername = Tags.CreateSubscription("@UserName", (result) => {
            Tags("LocVar_UserIsAuthorised").Write(Faceplate.Items("rectUserAuthDummy").CheckAuthorization(), Tags.Enums.hmiWriteType.hmiWriteNoWait);
        });
        subsTo_SystemUsername.Start();
    } catch (ex) {
        HMIRuntime.Trace("Faceplate LAS_Button3dStandard | \n" +
            "DisplayName: " + Faceplate.Parent.Name + "\n" +
            "Fehler beim Erstellen der Subscription zu @Username.\n" +
            "Fehler: " + ex, HMIRuntime.Trace.Enums.hmiSeverity.Error);
    };
Das stammt aus einem Button-Faceplate in welchem ich die Bedienbarkeit einer Taste "umschalte" indem ich ein transparentes Rechteck vor dem Button + ein Icon für den Gespert-Zustand ein- & ausblende.
Beispiel hab ich angehängt, der Code findet sich im Aufgebaut-Ereignis ab Zeile 12.
 

Anhänge

Zurück
Oben