WinCC Unified Schnittstellenvariable aus Faceplate schreiben - General error in Tag model occurred

Botimperator

Level-2
Beiträge
635
Reaktionspunkte
279
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin zusammen,

ich hab hier einen kleinen Testaufbau & einem Fehler bei dem ich nich weiterkomme.
Zum Aufbau:
Engineering: TIA V20 Update 1
Panel: MTP1200 6AV2 128-3MB06-0AX1, RT-Version V20.0.0.0
CPU: 1510SP F-1 PN 6ES7 510-1SJ01-0AB0, Firmware V2.9.7

Ich versuche grade ein I/O-Feld zu bauen, welches sich etwas anders Verhält als die Basisobjekte.
Anforderung:
- Fehlende Benutzerrechte sollen nicht durch eine Änderung der Transparenz, sondern durch einnen kleinen Icon (Schloss) dargestellt werden.
- die Variablenqualität soll konkret visualisiert werden, nicht nur einfach dieses Warndreieck. Symbol + Farbe für Upper/LowerLimit überschritten, Verbindung verloren, Wert OK.
- Die Dezimalstellen eines numerischen Wertes sollen auf der Schnittstelle parametrierbar sein, Lösung "zu Fuß" ist wie in diesem Beispiel ist unerwünscht.
- Die an das EA-Feld gekoppelte Variable muss einen Querverweis erzeugen (Keine Parametrierung des Variablennamens über Kofigurationsstring)
- Möglichst eine Lösung für alle gängigen Variablen-Datentypen. Nicht ein Faceplate je Datentyp.

Nach einigem Gefummel habe ich für den Größten Teil der Anforderungen in einer Faceplate gelöst bekommen,
ich scheitere aber daran aus dem Faceplate einen Wert auf die parametrierte SPS-Variable zu schreiben.
Wird am Faceplate-Interface eine interne HMI-Variable parametriert, funktioniert das Eingeben/schreiben von Werten.
Das Problem tritt NUR bei SPS-Variablen auf (╯°□°)╯︵ ┻━┻

Zum Aufbau der Lösung bzw. dem Problem:
Da ich keine beliebige Variable übergeben kann, musste ich für jeden Typ eine Schnittstellenvariable anlegen & diese Parametrierung dann per Script auswerten.
1745413003888.png
=> Das funktioniert soweit.

Die Variable ist soweit "normal" angelegt, ohne Range oder ähnliches
1745413089284.png
1745413106022.png

Das Faceplate selbst besteht aus einem normale IO-Field & diversen Icons.
1745413345404.png
=> Funktioniert auch prinzipiell soweit

Um die Benutzereingabe wieder auf die parametrierte Schnittstelle zu schreiben habe ich am "input finished"-Event des IO-Fields ein entsprechendes Script gehängt.
Dieses sollte den neuen Wert nehmen, prüfen (fehlt noch) und auf die am Interface parametrierte HMI-Variable schreiben.
So weit so einfach...

Javascript:
export function ioField_OnInputFinished(item, value) {
    try {
        let newInputValue;
        let writeErr = 0;
        //=========================
        //Expliziter Cast auf den Datentyp der angekoppelten Variable
        switch (typeof(Tags(HmiTagPropertyName).Read(Tags.Enums.hmiReadType.hmiReadCache))) {
        case "number":
            newInputValue = Number(value);
            //Kommaverschiebung berücksichtigen
            if (Faceplate.Properties.PrmIoFieldDecimalPlaces != 0) {
                newInputValue *= Math.pow(10, Faceplate.Properties.PrmIoFieldDecimalPlaces);
            }
            break;
        case "string":
            newInputValue = String(value);
            break;
        default:
            newInputValue = value;
            HMIRuntime.Trace("Faceplate " + Faceplate.Name + " | \n" +
                "Parent.Name: " + Faceplate.Parent.Name + "\n" +
                "Fehler beim onInputFinished von ioField - Kein Typecast für den Datentyp der angekoppelten HMI-Variable definiert.\n" +
                "Fehler: " + ex, HMIRuntime.Trace.Enums.hmiSeverity.Error);
            break;
        };
        //=========================
        //Schreiben des Eingabewertes auf die Interfacevariable
        //writeErr = Tags(HmiTagName).Write(newInputValue, Tags.Enums.hmiWriteType.hmiWriteWait);
        writeErr = Tags.SysFct.SetTagValue(HmiTagPropertyName, newInputValue);
        if (writeErr != 0) {
            HMIRuntime.Trace("Faceplate " + Faceplate.Name + " | \n" +
                "Parent.Name: " + Faceplate.Parent.Name + "\n" +
                "Fehler beim Schreiben des Eingabewertes in das gekoppelte Tag.\n" +
                "Fehler: " + HMIRuntime.GetDetailedErrorDescription(writeErr) + ", Fehlernummer: " + writeErr + "\n" +
                "InterfaceTagName: " + HmiTagPropertyName, HMIRuntime.Trace.Enums.hmiSeverity.Error);
        };
        //=========================
        //Debug:
        HMIRuntime.Trace("Faceplate " + Faceplate.Name + " | \n" +
            "Parent.Name: " + Faceplate.Parent.Name + "\n" +
            "Tagname: " + HmiTagPropertyName + "\n" +
            "Datentyp der Zielvariable: " + typeof(Tags(HmiTagPropertyName).Read()) + "\n" +
            "Datentyp der Eingabe vom ioField: " + typeof(value) + "\n" +
            "Typ des Wertes zum Schreiben: " + typeof(newInputValue) + "\n" +
            "Fehlernummer: " + Tags(HmiTagPropertyName).LastError + " Beschreibung: " + Tags(HmiTagPropertyName).ErrorDescription, HMIRuntime.Trace.Enums.hmiSeverity.Info);
        //=========================
        Tags("LocVar_StatusIconsAreVisible").Write(true, Tags.Enums.hmiWriteType.hmiWriteNoWait);
        //==================================================
        //Schnittstellenereignis auslösen
        let parameters = {
            ValueNew: newInputValue
        };
        Faceplate.RaiseEvent("EventIoFieldOnInputFinished", parameters);
        //=========================
        //Debug:
        HMIRuntime.Trace("Neuer Wert auf " + HmiTagPropertyName + " geschrieben, Ausgabewert: " + newInputValue + " typ: " + typeof(newInputValue), HMIRuntime.Trace.Enums.hmiSeverity.Info);

    } catch (ex) {
        HMIRuntime.Trace("Faceplate " + Faceplate.Name + " | \n" +
            "Parent.Name: " + Faceplate.Parent.Name + "\n" +
            "Fehler beim onInputFinished von ioField.\n" +
            "Fehler: " + ex, HMIRuntime.Trace.Enums.hmiSeverity.Error);
    };
}

Der explizite Typecast der Eingabe (kommt immer im Format "String") ist nicht zwingend notwendig, ist nur während der Fehlersuche reingekommen.
Mein Fehler tritt beim eigentlichen Schreiben auf:
Javascript:
        //=========================
        //Schreiben des Eingabewertes auf die Interfacevariable
        //writeErr = Tags(HmiTagName).Write(newInputValue, Tags.Enums.hmiWriteType.hmiWriteWait);
        writeErr = Tags.SysFct.SetTagValue(HmiTagPropertyName, newInputValue);
        if (writeErr != 0) {
            HMIRuntime.Trace("Faceplate " + Faceplate.Name + " | \n" +
                "Parent.Name: " + Faceplate.Parent.Name + "\n" +
                "Fehler beim Schreiben des Eingabewertes in das gekoppelte Tag.\n" +
                "Fehler: " + HMIRuntime.GetDetailedErrorDescription(writeErr) + ", Fehlernummer: " + writeErr + "\n" +
                "InterfaceTagName: " + HmiTagPropertyName, HMIRuntime.Trace.Enums.hmiSeverity.Error);
        };
        //=========================

"HmiTagPropertyName" enthält den Namen der parametrierten Schnittstellenvariable, in diesem Fall "HmiVarProcessValue7_Word".
Sobald eine "richtige" SPS-Variable parametiert ist (wie gesagt: interne Variablen funktionieren) bekomme ich folgenden Trace-Eintrag.
Code:
session: 0001, trace: Trace(): Faceplate LAS_IoFieldStandard_V_0_0_68 |
Parent.Name: Faceplate container_1
Fehler beim Schreiben des Eingabewertes in das gekoppelte Tag.
Fehler: General error in Tag model occurred., Fehlernummer: 2148545512
InterfaceTagName: HmiVarProcessValue7_Word
ScriptContext: HMI_RT_2::12111_Application_SubNav_1_Home
Module: /screen_modules/swContent/swSubNavContent/HMI_RT_2::12111_Application_SubNav_1_Home/faceplate_modules/LAS_IoFieldStandard_V_0_0_68/Events.js
Function: ioField_OnInputFinished
Ein "richtiger" Javascript-Fehler wird nicht geworfen, die try..catch Struktur bleibt inaktiv.
Der Wert der parametierten SPS-Variable wird nicht geändert.

Ich habs auch schon mit dem normalen Schreibzugriff probiert
Javascript:
writeErr = Tags(HmiTagName).Write(newInputValue, Tags.Enums.hmiWriteType.hmiWriteWait);
Damit passiert schlicht gar nichts.
Kein Javascript-Fehler, kein Eintrag in "writeErr", keine Änderung der Variable.

Der zweite Trace, also der, der auch .LastError ausgibt, gibt ebenfalls nicht mehr Infos her:
Code:
session: 0001, trace: Trace(): Faceplate LAS_IoFieldStandard_V_0_0_68 |
Parent.Name: Faceplate container_1
Tagname: HmiVarProcessValue7_Word
Datentyp der Zielvariable: number
Datentyp der Eingabe vom ioField: string
Typ des Wertes zum Schreiben: number
Fehlernummer: 0 Beschreibung:
ScriptContext: HMI_RT_2::12111_Application_SubNav_1_Home
Module: /screen_modules/swContent/swSubNavContent/HMI_RT_2::12111_Application_SubNav_1_Home/faceplate_modules/LAS_IoFieldStandard_V_0_0_68/Events.js
Function: ioField_OnInputFinished

Weiß jemand von euch was das Ding mit "General error in Tag model occurred" meinen könnte?
Selbst der Siemens AKG konnte weder mit dem Text, noch mit der Fehlernummer, etwas anfangen.
Ich hab das Faceplate an diesen Post angehängt, falls einer von euch mal Muße hat zu testen ob es sich nur bei mir ziert.

Und ganz vergessen:
Inidrekte Adressierung des Tags am IO-Feld funktioniert nicht, da dies sich wieder mit dem korrigieren der Nachkommastelle beißen würde.
Bzw. habe ich keine Möglichkeit gefunden beides zu kombinieren.
 

Anhänge

OK, ich raffs nicht mehr....

Ich hab zu Testzwecken, zusätzlich zur SPS, mal ein normales EA-Feld neben das Faceplate gesetzt (beide für die gleiche HMI-Variable).
Dabei ist mir folgendes Verhalten aufgefallen:
  • Wenn ich dem Faceplate und dem EA-Feld keine Authorization zuweise (also "none") kann ich sowohl im Faceplate, also auch im EA-Feld, den Wert verändern solange (!) kein Benutzer am HMI angemeldet ist.
  • Sobald ein Benutzer angemeldet wird, reagiert das EA-Feld bei Eingabe mit einem roten Blinken & der Wert wird nicht übernommen.
    Das Faceplate reagiert mit dem oben beschriebenen "General error in Tag model occurred."-Fehler.
  • Wenn eine Authorization parametriert wird & ein Benutzer mit entsprechendem Recht angemeldet wird, reagieren Faceplate/EA-Feld mit dem identischen Fehlerbild (rotes Blinken / general Error).
Dieses Verhalten betrifft alle angelegten Benutzer.
Die Benutzerverwaltung ist als "lokal" angelegt.
Jedem Benutzer wurde nur eine einzige Rolle zugewiesen.

Es ist also irgendwas mit den Benutzerrechten, aber was?
(°ー°〃)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ok...ich hab es jetzt mal soweit drauf eingegrenzt, dass es mit den benutzerdefinierten Rollen zusammenhängt.

Sobald ich dem Benutzer eine benutzerdefinierte Rolle zuweise, tritt das in #2 beschriebene Verhalten auf.
Es ist dabei irrelevant ob der benutzerdefinierten Rolle auch benutzerdefinierte Rechte zugewiesen wurde oder nicht.
Ich hab die benutzerdefinierten Rollen auch testweise mal gelöscht, alles übersetzt & nochmal frisch angelegt (ohne Änderung).
Die systemseitig angelegten Rollen funktionieren hingegen wie erwartet.

Ist da irgendwas bekannt, dass die lokale Benutzerverwaltung sich mit benutzerdefinierten Rollen beißt?
 
Zurück
Oben