Sonstiges Tc3 hmi (TcHmi.Symbol.readEx2)

TwinCatBastian

Level-1
Beiträge
5
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich versuche gerade ein Polygon-Control mit Array Koordinaten (ARRAY [1..1,0..99] OF STRING(80)) der SPS zu versorgen.

Code:
(function (TcHmi) {

    var ArrayToString = function () {
        TcHmi.Symbol.readEx2('%s%PLC1.MAIN.arrTriStr%/s%', function (data) {
            if (data.error === TcHmi.Errors.NONE) {
                var response = data.value;
                var value = "";
// einen langen String, durch Zugriff auf alle Array Elemente, aufbauen
                for (var i = 0; i < response[0].length; i++) {
                    value += response[0][i];
                }
                console.log(value);
            }
            else {
                console.log("Error.");
                return;
            }
        });
    };
    
    TcHmi.Functions.registerFunction('ArrayToString', ArrayToString);
})(TcHmi);

Eingebunden habe ich das ganze als function binding unter Common->Points im Control, nur leider fehlt mir der return damit die Daten "ankommen". Sollte ich das Ergebnis in ein internes Symbol schreiben oder wie sähe die elegante Lösung aus?

Danke
Beste Grüße
Bastian
 
Also per CodeBehind und mit writeEx in ein Internal/Server Symbol funktioniert es, aber leider habe ich keine dynamische Aktualisierung der Daten. Inwiefern kann ich ein Interval einbetten in die Abfrage (readEx2 bzw. writeEx)?

/edit
Mit "setInterval" im JavaScript funktioniert es zumindest, aber ich bin mir nicht sicher ob es eine schönere Lösung gibt.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Du hast zwei hier Probleme. Einmal fehlende "dynamische Aktualisierung" und "asynchronen Rückgabewert" der Funktionen. Ich werde erst die Lösung des zweiten Problems erläutern, aber die Lösung des ersten Problems löst gleich beide. Also lese erstmal das ganze vollständig.

Du hast eine synchrone Funktion, aber deine Daten asynchron ankommen. Also muss deine Funktion auch asynchron werden.
Also stell im Editor der .function.json den WaitMode auf "Asynchronous". Dann wird er deine Funktion ändern in:
var ArrayToString = function (ctx) {

Hier kannst du dann im Callback deiner read Funktion (an der Stelle von console.log)
ctx.success(value);
bzw im Fehlerfall
// Inform the system that we are done but had an error ctx.error(data.error, {
code: data.error,
message: TcHmi.Errors[data.error],
reason: 'Function: ArrayToString failed',
domain: 'Function',
errors: (data.details ? [data.details] : undefined)
});
nutzen. Alle normalen returns sind damit ohne Rückgabewert.
Ein großes Beispiel mit asynchronen Funktionen findest du auch hier: https://infosys.beckhoff.com/conten...eering/5872675083.html?id=6850566722956567501


ABER damit hast du zwar was über asynchrone Funktionen gelernt, aber noch keine automatische Aktualisierung deiner Werte :)

Ich würde für den Serverpfad %s%PLC1.MAIN.arrTriStr%/s% auch eine Variable data mit dem richtigen Typen anlegen. Bindable lässt du auf "yes, pass value".
Wenn du diese Funktion dann als function binding unter Common->Points im Control angibst, kümmert sich das System um die Änderungsproblematik und ruft dich direkt mit dem fertigen Array als Parameter auf. Damit kann deine Funktion synchron bleiben und du nutzt einfach return value.
 
Ok, zunaechst danke fuer die Erlaeuterung, den Hinweis bzgl der asynchronen Funktion habe ich verstanden. Den letzten Part verstehe ich nicht ganz bzw. vielleicht war meine Erklaerung falsch.

Also:
In der SPS fuelle ich ein arrStr := ARRAY (0..99) OF STRING(80) mit Koordinaten, z.B. arrStr[0] := 0,100, arrStr[1] = 20,80 usw.
Daraus "baue" ich mir einen String -> var result = "0,100 20,80 ..." -> ctx.success(result), diesen moechte ich an mein Polygon-Control weitergeben und automatisch aktualisieren.

Nun meine Frage: Wie ist dein Tipp zu verstehen bzgl. einer Variable "data" mit Bindable usw.
 
Zuletzt bearbeitet:
Hi Bastian,

ich würde mir eine normale Init Funktion (kein CodeBehind) machen und diese beim Desktop onAttached Event aufrufen.

In der registrierst du dir ein Event auf dein Server Smbol, dieser wird beim initialisieren einmal ausgeführt und dann immer bei einer Änderung.

Hier ein Beispiel wenn die Daten von der SPS schon fertig als String kommen würden...

(function (TcHmi) {
var init = function () {
TcHmi.EventProvider.register('%s%PLC1.MAIN.arrTriStr%/s%', function (e, d) {

let poly = TcHmi.Controls.get('Poly');
poly.setPoints(d);
});
};
TcHmi.Functions.registerFunction('init', init);
})(TcHmi);

Falls du aber keine Verbindung zur SPS hast oder das Symbol nicht existiert wird der Event einfach nicht ausgeführt, es gibt also kein Fehler in der Console, daran muss man halt denken.

Gruß Mathias
 
Zuletzt bearbeitet:
Ok, zunaechst danke fuer die Erlaeuterung, den Hinweis bzgl der asynchronen Funktion habe ich verstanden. Den letzten Part verstehe ich nicht ganz bzw. vielleicht war meine Erklaerung falsch.

Also:
In der SPS fuelle ich ein arrStr := ARRAY (0..99) OF STRING(80) mit Koordinaten, z.B. arrStr[0] := 0,100, arrStr[1] = 20,80 usw.
Daraus "baue" ich mir einen String -> var result = "0,100 20,80 ..." -> ctx.success(result), diesen moechte ich an mein Polygon-Control weitergeben und automatisch aktualisieren.

Nun meine Frage: Wie ist dein Tipp zu verstehen bzgl. einer Variable "data" mit Bindable usw.
Vielleicht hilft dir ein Screenshot aus dem verlinkten Beispiel zum Verständnis:

spsforum_function.PNG
Deine Funktion kriegt als Parameter direkt die SPS Variable.
 
Zurück
Oben