WinCC Unified Unified PC Runtime V20 führt Systemfunktion nicht aus

Zuviel Werbung?
-> Hier kostenlos registrieren
Wow, das wäre was für mich :sick:

Ich verwende in meinen HMI-Projekten massiv Skripte, in denen ich Variablennamen quasi zusammenbaue und diese außerdem sehr häufig nicht direkt an Controls projektiert sind. Das wäre dann ja so gar nicht mehr möglich ...
 
Ich frag mich nur, wann in dieser Konstellation ein catch ausgelöst werden kann. Wenn der Befehl nie gesetzt wird. Ohne das try catch wird wohl, falls der Befehl nicht erfolgreich geschrieben wurde trotzdem mein Bild gewechselt.
Das catch{} wird ausgelöst sobald eine exception geworfen wird.
Also wenn du versuchst auf etwas zuzugreifen, das im aktuellen Kontext nicht existiert oder du einen Tippfehler hast.
Groß-/Kleinschreibung ist hier ein beliebter Fehler.
Ausführliche Beschreibung siehe hier.
Im aktuellen Fall ist das catch{} lediglich in dem Sinne von Interesse, dass es nicht aufgerufen wird.
Dein Problem wird also nicht von einem nur in speziellen Situationen auftretendem Kontextfehler oder ähnlichem verursacht.
Dein Bildname existiert, Bildpfad ist ok, keine Tippfehler, usw...

Der try{} Teil wird nach einem Fehler übrigens nicht fortgesetzt, sondern verzweigt bei der ersten exception in den catch{}.
Würde das Schreiben der Variable eine exception werfen, würde dein Bild also eben nicht gewechselt werden.
ich benutze dieses Verhalten beispielsweise hier um zu testen ob bestimmte Bildfenster in der aktuellen Verschachtelungs-Hierarchie geladen sind.
Also es funktioniert besser, aber trotzdem habe ich ab und an mal Aussetzer. Im TraceViewer wird kein Fehler aus dem try catch geschmissen.
Das wird bei deinem speziellen Problem auch nicht passieren, da in deinem Script kein Fehler im eigentlichen Sinne auftritt.
Wenn ich den Fehler richtig zerdenke passiert folgendes:
- du stößt den Schreibbefehl an. Es wird jetzt im Kontext des aktuellen Bildes ein Befehl an den Variablen-Verwaltungsdienst gegeben.
- Nachdem der Befehl weitergegeben wurde, wird in deinem auslösenden Script weitergemacht.
- Jetzt wird das Bild gewechselt. Dies beginnt mit dem Abbau des aktuellen Bildes und der damit zusammenhängenden Beendigung aller in diesem Kontext gestarteten Aktionen.
- Gelegentlich ist dein Schreibbefehl aber noch nicht ausgeführt und wird aufgrund des Bildabbaus vor dessen Ausführung abgebrochen.
=> Bildwechsel erfolgt, das Schreiben der Variable wird aber abgewürgt.

Poste mal bitte den Auszug des TraceViewers wenn das Fehlverhalten auftritt.
Ich komm nicht mehr drauf wie die Meldung genau hieß, aber irgendein Modul schmeißt einen ganz kryptischen Fehler wenn ein aktiver Scriptkontext abgebaut wird.

Ich bin eigentlich davon ausgegangen, dass Tags().Write() in Verbindung mit hmiWriteWait ein synchrones Verhalten erzwingt, was hier anscheinend nicht der Fall zu sein scheint (っ °Д °; )っ

Probier es mal mit dem Promise von Tag.SetBit().
Javascript:
try {
    let befehl = Tags("DB_Daten_Befehle_xxx");
    befehl.SetBit(1)
    .then(() => {
        HMIRuntime.Trace("\nPromise von SetBit wurde resolved.\n" +
            "Bildobjekt: " + item.Name + "\n" +
            "Bild: " + Screen.Name + "\n" +
            "Bildpfad: " + Screen.Parent.Path, HMIRuntime.Trace.Enums.hmiSeverity.Info);
        //Nachdem SetBit erfolgreichen vollzug gemeldet hat kann das Bild gewechselt werden.
        HMIRuntime.UI.SysFct.ChangeScreen("Name des neuen Bilds", ".");
    })
    .catch((ex) => {
        HMIRuntime.Trace("\nPromise von SetBit wurde rejected.\n" +
            "QualityCode der Variable: " + befehl.QualityCode + "\n" +
            "Bildobjekt: " + item.Name + "\n" +
            "Bild: " + Screen.Name + "\n" +
            "Bildpfad: " + Screen.Parent.Path + "\n" +
            "Fehler: " + ex, HMIRuntime.Trace.Enums.hmiSeverity.Error);
    });
} catch (ex) {
    HMIRuntime.Trace("\nAllgemeiner Fehler im Bildwechsel-Befehl.\n" +
        "QualityCode der Variable: " + befehl.QualityCode + "\n" +
        "Bildobjekt: " + item.Name + "\n" +
        "Bild: " + Screen.Name + "\n" +
        "Bildpfad: " + Screen.Parent.Path + "\n" +
        "Fehler: " + ex, HMIRuntime.Trace.Enums.hmiSeverity.Error);
}

Und wenn das nicht funktioniert gäbe es auch noch die Möglichkeit per HMIRuntime.Timers.SetTimeout() den Bildwechsel-Befehl um ein paar Milisekunden zu verzögern.
Das wäre zwar hartes Quick&Dirty, aber...
1765224349750.png
Ich hab damit hier auch schonmal eine hässliche Ausgeburt der Hölle basteln müssen, weil es einfach nicht anders funktionieren wollte ¯\_(ツ)_/¯
Wow, das wäre was für mich :sick:

Ich verwende in meinen HMI-Projekten massiv Skripte, in denen ich Variablennamen quasi zusammenbaue und diese außerdem sehr häufig nicht direkt an Controls projektiert sind. Das wäre dann ja so gar nicht mehr möglich ...
Keine Sorge, in dem Punkt ist es mit Unified noch einfacher geworden.
Tags() erwartet lediglich einen String um ein Tag-Objekt zu erzeugen.
Diesen kannst du dir beliebig zusammenstellen, mit allen Schikanen die Javascript so hergibt.

Was Scripting angeht arbeite ich inzwischen lieber mit Unified.
Es ist zwar immer noch stellenweise fürn 🍑, aber nicht mehr so FLŰGGÅƏNK∂€ČHIŒβØL∫ÊN-Style mäßig fürn 🍑.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Keine Sorge, in dem Punkt ist es mit Unified noch einfacher geworden.
Tags() erwartet lediglich einen String um ein Tag-Objekt zu erzeugen.
Diesen kannst du dir beliebig zusammenstellen, mit allen Schikanen die Javascript so hergibt.
Das Zusammenbauen des Namens ist nicht das Problem, nur würde der Variablenwert ohne "zyklisch fortlaufende" Erfassung ja im Skriptkontext niemals aktuell sein. (So war/ist es ja bei WinCC Comfort/Advanced).

Oder verstehe ich da etwas falsch bzw. ist dies in Unified anders?
 
Also es funktioniert besser, aber selbst mit Timeout noch nicht 100%. Habe mit Siemens telefoniert und der meinte wohl es kann am IN/OUT liegen. Da ich die HMI Variablen dort auch verwenden und zwischendurch überschrieben werden. Da gibt es wohl viele die das Problem mit neueren Steuerungen haben.
 
Das ist dann wahrscheinlich die Problematik der Vermischung von optimierten und nicht optimierten Bausteinen. Das steht aber auch so im Handbuch.
 
Also es funktioniert besser, aber selbst mit Timeout noch nicht 100%. Habe mit Siemens telefoniert und der meinte wohl es kann am IN/OUT liegen. Da ich die HMI Variablen dort auch verwenden und zwischendurch überschrieben werden. Da gibt es wohl viele die das Problem mit neueren Steuerungen haben.
Das ist dann irgendwie schräg....
Wenn es an dem Schreib-/Lesezugriff im SPS Programm liegen würde, wäre zumindest das HMI nicht schuld am beschriebenen Verhalten.
Hast du ne Option den Befehl über eine Variable zu übergeben, die nicht von einem Schreibbefehl zufällig überschieben werden könnte?

Du hast konkret den Code mit SetBit() ausprobiert?
Trace mal den aktuellen Variablenwert der Befehlsvariable mit.
Dann wissen wir zumindest ob es an der HMI-Variable liegt oder auf seiten der SPS...
Javascript:
.then(() => {
    //Nach erfolgter Schreiboperation den Variablenwert direkt aus der SPS lesen und als Trace ausgeben
    HMIRuntime.Trace("\nPromise von SetBit wurde resolved.\n" +
        "Variablenwert der Befehlsvariable: " + befehl.Read(HMIRuntime.Tags.Enums.hmiReadType.hmiReadDirect) + "\n" +
        "QualityCode der Variable: " + befehl.QualityCode + "\n" +
        "Bildobjekt: " + item.Name + "\n" +
        "Bild: " + Screen.Name + "\n" +
        "Bildpfad: " + Screen.Parent.Path, HMIRuntime.Trace.Enums.hmiSeverity.Info);
    //Nachdem SetBit erfolgreichen vollzug gemeldet hat kann das Bild gewechselt werden.
    HMIRuntime.UI.SysFct.ChangeScreen("Name des neuen Bilds", ".");
})
Probleme, die sich aus der Kombination von Unified & neueren Steuerungen wäre mir nichts bekannt.
Zumindest nichts, was nicht auch bei jeder anderen Steuerungs/HMI-Kombination zu beachten wäre...

Das ist dann wahrscheinlich die Problematik der Vermischung von optimierten und nicht optimierten Bausteinen. Das steht aber auch so im Handbuch.
Das sollte eigentlich nichts ausmachen...
Ich hab in meinen Projekten, speziell in Retrofit-Anlagen, häufig eine wilde Mischung aus optimierten und nicht optimierten Bausteinen & S7-300/400/1500 verschiedener Altersklassen.
Hat bisher keinen Unterschied gemacht ¯\_(ツ)_/¯
Oder meinst du das Thema mit Performance innerhalb der SPS?
Das sollte aber im Bezug auf die HMI-Kommunikation (eigentlich) keinen Unterschied machen.

Das Zusammenbauen des Namens ist nicht das Problem, nur würde der Variablenwert ohne "zyklisch fortlaufende" Erfassung ja im Skriptkontext niemals aktuell sein. (So war/ist es ja bei WinCC Comfort/Advanced).

Oder verstehe ich da etwas falsch bzw. ist dies in Unified anders?
Ein bisschen anders.
Man muss im Bezug auf Advanced-HMIs manchmal etwas umdenken um das gewünschte Verhalten zu erreichen.
Du kannst bei Unified zwischen "cyclic in operation" und "on demand" wählen (weiß die Bezeichnung in der deutschen Oberfläche grade nicht auswendig).
Ein richtiges "zyklisch fortlaufend", also Variable dauerhaft unabhängig von der Verwendung aktualisieren, gibt es nicht mehr.
Bei "cyclic in operation" wird die HMI-Variable nur aktualisiert wenn diese auch irgendwo im aktuellen Bild oder in einem Log verwendet wird.
Dazu zählen auch Subscriptions auf das betreffende Tag oder dessen TagSet (falls vorhanden/verwendet) & ist damit analog zu "zyklisch im Betrieb".
Bei "on demand" werden die Werte nur aktualisiert wenn du die Variablen per SysFct.UpdateTag() explzit aus der SPS liest.
Dazu kannst du in den Eigenschaften der HMI-Variablen eine Update-ID der oder den Variablen vergeben.
Das eignet sich beispielsweise für die triggerbasierte Aktualiserung einer großen Menge von Variablen, die während der Projektierung per Update-ID gruppiert wurden.
Zusätzlich kannst du bei Lese- & Schreiboperationen auf ein Tag oder TagSet den Read-/Write Type optional angeben.
Damit kannst du (oder zumindest sollte es so sein) explizit angeben ob der Wert aus dem Cache, also der HMI Variable, oder direkt aus der SPS gelesen oder in diese geschrieben werden soll.

Der zuerst von mir vorgeschlagene Code
Javascript:
let befehl = Tags("DB_Daten_Befehle_xxx");
befehl.Write(1, Tags.Enums.hmiWriteType.hmiWriteWait);
hätte eigentlich einen direkten, synchronen Schreibzugriff auf die SPS-Variable auslösen sollen.
(synchron = das Script wartet bis die Funktion ausgeführt wurde, bevor die nächste Code-Zeile bearbeitet wird)
Wieso das anscheinend nicht der Fall gewesen sein soll, kann ich mir gerade nicht so wirklich schlüssig erklären (。﹏。*)
Wenn es, wie von @Monstablokaz erwähnt, an der InOut-Variable innerhalb der SPS liegen sollte, wäre das HMI unschuldig.
Als Ferndiagnose ist sowas halt schwer einzugrenzen...
 
Zuletzt bearbeitet:
Das sollte eigentlich nichts ausmachen...

Falsch. Bei Aufruf eines optimierten Bausteins von einem nicht-optimierten Baustein aus werden Strukturen an InOut nicht ByRef sondern ByValue übergeben. Am Ende der Abarbeitung wird dann die Kopie (samt zwischenzeitlich vom SPS-Programm geänderten Werten) auf die Ausgangsstruktur zurückkopiert. Wenn jetzt das HMI in der Zwischenzeit eine SPS-Variable innerhalb der Struktur verändert hat, ist die Änderung damit platt gemacht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn jetzt das HMI in der Zwischenzeit eine SPS-Variable innerhalb der Struktur verändert hat, ist die Änderung damit platt gemacht.
genau. Wobei das eigentliche Problem ist die schon oft angesprochene "optimierte" asynchrone HMI-Kommunikation ohne Zykluskontrollpunkt, die man besonders beachten muss. Halt die üblichen Multitasking-Probleme.
 
Was meinst du damit?
dass die HMI-Kommunikation einen Baustein unterbricht, und Variablenwerte in IN/OUT-Strukturen ändert und danach schreibt der Baustein die IN/OUT-Werte zurück und die Änderungen durch die HMI-Kommunikation sind wieder weg. Wie Oberchefe bereits in #31 erklärt hat. Die eigentliche Ursache des Problems ist das Multitasking - die unkooperativen azyklischen Unterbrechungen des SPS-Programms durch die HMI-Kommunikation.
Forumsuche: HMI Zykluskontrollpunkt
 
Ich sehe gerade ich nutze doch eine Variable aus einen nicht optimierten Datenbaustein. :confused::oops:

Also werden die Werte laut Handbuch als "Call-by-value" übergeben und nicht "by reference". Das heißt am Ende ja nur alle DBs und FBs anpassen und schon ist es "gelöst"?
 
Zurück
Oben