Eine Methode ausführen

Jede Operation dieser Anwendung - Matching, Anlegen von Vorlagen und Modulverwaltung - wird auf dieselbe Weise gestartet und meldet ihren Ausgang auf dieselbe Weise.

Der Aufbau einer Operation

Eine Operation liegt unter einer eigenen Adresse und hat immer drei Teile:

<operation>/execute                 write here to run it
<operation>/input/...               the values it works on
<operation>/output/status-code      what happened, as a number
<operation>/output/status-text      what happened, in words

Manche Operationen haben unter output/ mehr - ein Matching-Ergebnis oder den Pfad einer geschriebenen Datei -, aber execute, status-code und status-text sind immer vorhanden.

Eine Operation ausführen

  1. Schreiben Sie die Eingabeknoten.

  2. Schreiben Sie auf execute. Der Wert spielt keine Rolle; der Schreibvorgang selbst löst die Operation aus.

  3. Lesen Sie output/status-code, um zu erfahren, ob sie erfolgreich war.

Das Schreiben auf execute ist ein blockierender Aufruf: Er kehrt zurück, wenn die Operation abgeschlossen ist. Sie müssen also kein „ready"-Flag pollen und keinen Zustand in Ihrem Programm verfolgen. Eingaben behalten ihre Werte zwischen den Durchläufen, sodass eine wiederholte Operation nur Schritt 2 braucht.

Den Ausgang prüfen

output/status-code ist eine vorzeichenbehaftete Zahl, und allein das Vorzeichen sagt Ihnen, ob es funktioniert hat:

Wert Bedeutung

größer als 0

Die Operation war erfolgreich

0

Die Operation ist seit dem Start der Anwendung nicht gelaufen

kleiner als 0

Die Operation ist fehlgeschlagen und hat nichts erzeugt

Die Prüfung in einer SPS ist also einfach status-code < 0. Einen bestimmten Code brauchen Sie nur, wenn Sie auf verschiedene Fehler unterschiedlich reagieren möchten - etwa auf eine fehlende Vorlage anders als auf eine Kamera, die nicht antwortet.

output/status-text enthält denselben Ausgang als Satz und benennt den fehlerhaften Wert, wenn es einen gibt:

ok: 3 match(es) using 'screw.png'
error: crop/startX + crop/width (100 + 900 = 1000) exceeds the image width 640

Lesen Sie ihn, wenn etwas schiefgeht; bauen Sie keine Logik darauf auf, denn der Wortlaut kann sich zwischen Releases ändern. Die vollständige Liste der Codes steht in Ausführungsstatus.

Der Grund kommt auf output/status-text an, nicht in der Antwort auf den execute-Schreibvorgang selbst. Ein fehlgeschlagener Schreibvorgang antwortet nur mit einem Statuscode - über REST ein bloßes 400. Der Data Layer verwirft jedes Detail, das ein Provider an einen fehlgeschlagenen Aufruf anhängt. Deshalb ist das anschließende Lesen von output/status-text der Weg, um herauszufinden, was falsch war. Die Ergebniscodes eines Schreibvorgangs auf beiden Data Layern sind in Ergebnisse eines Methodenaufrufs aufgeführt.

Derselbe Text wird in das Anwendungsprotokoll geschrieben, sodass ein Fehler auch ganz ohne Zugriff auf den Data Layer diagnostizierbar ist: auf ctrlX OS im ctrlX Logbook oder mit journalctl, auf einem PC in der Konsolenausgabe der Anwendung. Sind mehrere Eingaben falsch, erhält jede eine eigene Warnzeile.

Eine Operation zur Zeit

Ein Modul führt jeweils eine Operation aus. Wird eine zweite gestartet, während die erste noch läuft, wird sie nicht in eine Warteschlange gestellt - sie kehrt sofort mit Statuscode -1 (busy) zurück und tut nichts. Der Schreibvorgang selbst antwortet mit TooManyOperations (ctrlX: DL_TOO_MANY_OPERATIONS), siehe Eine Operation zur Zeit.

Die Sperre gilt pro Modul, sodass verschiedene Module parallel matchen - eine zweite Kamera wird von der ersten nicht aufgehalten. system/create-object hat eine eigene Sperre, sodass das Anlegen einer Vorlage das Matching nicht blockiert und zwei Anlagevorgänge nicht kollidieren können.

Die Ausgaben gehören zum startenden Durchlauf

Jede Methode leert ihre eigenen Ausgabeknoten, sobald sie beginnt - find-object sein output/result, create-object sein output/object-path. Sie werden geleert, bevor irgendetwas fehlschlagen kann, sodass ein Durchlauf, der aus irgendeinem Grund fehlschlägt, sie leer hinterlässt, statt das Ergebnis eines früheren Durchlaufs zu behalten.

Das macht es sicher, eine Ausgabe zu lesen, ohne zuerst output/status-code zu prüfen: Was Sie sehen, ist entweder das Ergebnis dieses Durchlaufs oder nichts, nie ein veralteter Wert aus einem vorherigen Bild.

output/status-code und output/status-text sind die Ausnahme - sie beschreiben immer den letzten Versuch, und genau das ist ihr Zweck.

Lesen Sie eine Ausgabe, bevor Sie den nächsten Durchlauf auslösen. Die Ausgaben beschreiben den letzten Durchlauf, und der nächste Aufruf leert sie in dem Moment, in dem er beginnt. Erneut execute aufzurufen und dann das vorherige Ergebnis zu lesen, liefert nichts.

Der einzige Fall, der nichts leert, ist ein als -1 (busy) abgelehnter Aufruf: Er ist nie gelaufen und lässt die Ausgaben der laufenden Operation unberührt. Ein zweites execute, das unmittelbar nach dem ersten abgesetzt wird, hat also zwei mögliche Ausgänge, und sie unterscheiden sich:

  • der erste Durchlauf läuft noch - der zweite wird mit -1 abgelehnt, und die Ausgaben enthalten noch den Durchlauf davor;

  • der erste Durchlauf ist gerade fertig - der zweite wird angenommen und leert die Ausgaben, die der erste Durchlauf eben erst geschrieben hat.

Warten Sie, bis execute zurückkehrt, lesen Sie die Ausgaben, und lösen Sie erst dann den nächsten Durchlauf aus.