KI-GESTÜTZTE DOKUMENTATION
Was möchten Sie wissen?
Recipe-Skript
Ein Recipe-Skript ist ein kurzes JavaScript-Stück, das bei jeder Prüfung eines Rezepts nach den Tools ausgeführt wird. Es kann:
- über Pass oder Fail entscheiden mit Ihrer eigenen Logik und eine Begründung liefern
- eigene Bytes schreiben für die User Results der SPS
- Metadaten und Tags speichern mit der Aufnahme, sodass Sie sie in der Library finden
Jedes Rezept hat höchstens ein Skript, und es wird mit dem Rezept exportiert.
Editor öffnen
Scrollen Sie im Beurteilung-Schritt des Rezepts zu Recipe-Skript und klicken Sie auf Skripteditor öffnen.

Oben im Beurteilungsschritt wählen Sie aus, was die Beurteilung entscheidet: die Regeln oder das Recipe-Skript. Die Regeln laufen immer, und das Skript sieht deren Beurteilung. Wenn Sie die Einstellung auf die Regeln belassen, kann das Skript Pass oder Fail nicht ändern, aber seine Begründung, Metadaten, Tags und SPS-Bytes werden trotzdem angewendet. Das ist ein sicherer Einstieg: Fügen Sie ein Skript für die Begründung und die Bytes hinzu und lassen Sie die Regeln die Entscheidung treffen.

Wie es ausgeführt wird
Trigger → Capture and tools → Pass/fail rules → inspect(input) → Verdict, PLC User Results, Library, MQTT
Das Skript exportiert eine Funktion, inspect(input). Die Kamera ruft sie bei jeder Prüfung des Rezepts auf, nach den Tools und den Regeln. Die Linie wartet darauf, daher muss sie synchron und schnell sein: Sie hat standardmäßig 25 ms, bis zu 200 ms in den Einstellungen des Skripts, und ihre Zeit kommt zur Zykluszeit hinzu.
input enthält alles bisher. Es ist schreibgeschützt:
| Feld | Was es ist |
|---|---|
tools | Das Ergebnis jedes Tools, in der Reihenfolge der Ausführung |
tools_by_name | Dieselben Ergebnisse nach Toolnamen |
rules | Die Beurteilung der Regeln: judgment, pass, not_inspected |
vars | Ihre Variablen nach Namen. Eine Variable ohne Wert ist null |
vars_info | Für jede Variable: received_at, age_ms und source |
recipe | id, uuid und name |
trigger | id, source (zum Beispiel plc, gpio, http, manual) und metadata |
Jedes Toolergebnis hat name, type, judgment, pass, score, plc_slot, execute_ms, error, skipped_by und ein detail-Objekt, dessen Form vom Tool abhängt. Prüfen Sie type, bevor Sie detail lesen, zum Beispiel ai_fast_classifier (mit detail.regions), ai_ocr (mit detail.fields), ai_counting (mit detail.count) oder classical.barcode (mit detail.data).
Was es zurückgibt
Jedes Feld ist optional. Ein weggelassenes Feld behält das normale Verhalten der Kamera bei, sodass ein Skript nur die Begründung setzen und die Beurteilung den Regeln überlassen kann. Geben Sie nichts zurück, um nichts zu ändern.
| Feld | Bedeutung | Grenze |
|---|---|---|
judgment | "pass", "fail" oder "not_inspected" (true, false und null haben dieselbe Bedeutung). Wird nur verwendet, wenn der Beurteilungsschritt auf das Recipe-Skript eingestellt ist | |
reason | Text, der in der Library angezeigt und in Ergebnismeldungen (MQTT, HTTP API, Kameraskript) gesendet wird | 64 Zeichen |
plc_user_results | Bytes für die User Results der SPS, üblicherweise mit pack() erstellt | Die konfigurierte Größe der User Results |
metadata | Schlüssel-Wert-Paare, die mit der Aufnahme gespeichert und in ihren Library-Details angezeigt werden. Schlüssel sind Buchstaben, Ziffern und Unterstriche, beginnend mit einem Buchstaben; Werte sind Text, Zahlen oder true/false | 32 Schlüssel, Textwerte bis zu 256 Zeichen |
tags | Labels, die als Chips in der Library angezeigt werden, nach denen Sie filtern können | 16 Tags, je 32 Zeichen |
export function inspect({ tools_by_name, vars }) {
const ocr = tools_by_name["Serial"];
if (ocr?.type !== "ai_ocr" || !ocr.detail) {
return { judgment: false, reason: "no OCR result" };
}
const expected = vars["serial"];
if (typeof expected !== "string") {
return { judgment: null, reason: "serial not received" };
}
const read = ocr.detail.fields.map((f) => f.text_judged).join("");
const match = read === expected;
return { judgment: match, reason: match ? "serial matches" : "serial differs" };
}
Ausprobieren
Rezept-Skript-Playground
Teil ändern, Skript bearbeiten, Ausführen drücken. Das Skript erhält dieselbe Eingabe, die die Kamera an inspect() übergibt, und läuft unter denselben Regeln.
Ein AI-Klassifikations-Tool mit 10 Regionen, eine pro Pin. Klicken Sie auf einen Pin, um ihn umzuschalten.
Eingabeobjekt anzeigen
{
"recipe": {
"id": 3,
"uuid": "01a15a44-9a3c-72bb-ab4f-5481cce20093",
"name": "Sample recipe"
},
"trigger": {
"id": 4182,
"source": "plc",
"metadata": {}
},
"rules": {
"judgment": "fail",
"pass": false,
"not_inspected": false
},
"vars": {},
"vars_info": {},
"tools": [
{
"type": "ai_fast_classifier",
"id": "01a1-pins",
"name": "Pins",
"plc_slot": 1,
"judgment": "fail",
"pass": false,
"score": 0.9,
"execute_ms": 6,
"error": "none",
"skipped_by": "",
"detail": {
"regions": [
{
"label": "Pin 1",
"class_label": "seated",
"confidence": 0.97,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 2",
"class_label": "seated",
"confidence": 0.93,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 3",
"class_label": "seated",
"confidence": 0.95,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 4",
"class_label": "bent",
"confidence": 0.81,
"verdict": "fail",
"threshold": 0.5,
"pass": false
},
{
"label": "Pin 5",
"class_label": "seated",
"confidence": 0.91,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 6",
"class_label": "seated",
"confidence": 0.96,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 7",
"class_label": "seated",
"confidence": 0.94,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 8",
"class_label": "seated",
"confidence": 0.89,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 9",
"class_label": "seated",
"confidence": 0.98,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 10",
"class_label": "seated",
"confidence": 0.92,
"verdict": "pass",
"threshold": 0.5,
"pass": true
}
],
"overall": "fail"
}
}
],
"tools_by_name": {
"Pins": {
"type": "ai_fast_classifier",
"id": "01a1-pins",
"name": "Pins",
"plc_slot": 1,
"judgment": "fail",
"pass": false,
"score": 0.9,
"execute_ms": 6,
"error": "none",
"skipped_by": "",
"detail": {
"regions": [
{
"label": "Pin 1",
"class_label": "seated",
"confidence": 0.97,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 2",
"class_label": "seated",
"confidence": 0.93,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 3",
"class_label": "seated",
"confidence": 0.95,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 4",
"class_label": "bent",
"confidence": 0.81,
"verdict": "fail",
"threshold": 0.5,
"pass": false
},
{
"label": "Pin 5",
"class_label": "seated",
"confidence": 0.91,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 6",
"class_label": "seated",
"confidence": 0.96,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 7",
"class_label": "seated",
"confidence": 0.94,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 8",
"class_label": "seated",
"confidence": 0.89,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 9",
"class_label": "seated",
"confidence": 0.98,
"verdict": "pass",
"threshold": 0.5,
"pass": true
},
{
"label": "Pin 10",
"class_label": "seated",
"confidence": 0.92,
"verdict": "pass",
"threshold": 0.5,
"pass": true
}
],
"overall": "fail"
}
}
}
}Klicken Sie auf Ausführen, um zu sehen, wie diese Prüfung ausfallen würde.
Eine Simulation in Ihrem Browser. An der Kamera verwenden Sie Test im Skript-Editor, um den Entwurf vor dem Speichern an echten Aufnahmen auszuführen.
Bytes für die SPS schreiben
Geben Sie plc_user_results zurück, erstellt mit pack(layout, values). Die SPS liest es mit dem Ergebnis, vor der Inspection Completed-Flanke.
Beschreiben Sie die Bytes einmal als Layout: eine geordnete Liste von { name, type }-Feldern.
| Typ | Bytes |
|---|---|
u8, i8, bool | 1 |
u16le, u16be, i16le, i16be | 2 |
u32le, u32be, i32le, i32be, f32le, f32be | 4 |
u64le, u64be, i64le, i64be, f64le, f64be | 8 |
bits mit count | Ein Bit pro Wert, der erste Wert im niedrigsten Bit |
ascii oder utf8 mit length | Text, aufgefüllt oder (mit truncate: true) auf Länge gekürzt |
bytes mit length | Rohbytes |
pad mit length | Nullbytes, um eine Lücke zu überspringen |
const OUT = [
{ name: "regionOk", type: "bits", count: 80 },
{ name: "count", type: "u16le" },
];
export function inspect({ tools_by_name }) {
const classifier = tools_by_name["Classifier"];
if (classifier?.type !== "ai_fast_classifier" || !classifier.detail) return;
const regionOk = classifier.detail.regions.map((r) => r.pass).slice(0, 80);
return { plc_user_results: pack(OUT, { regionOk, count: regionOk.length }) };
}
Jeder Mehrbyte-Typ benennt seine eigene Byte-Reihenfolge, und die Kamera vertauscht niemals Bytes für Sie. Verwenden Sie die le-Typen bei EtherNet/IP und die be-Typen bei PROFINET. Die Skriptprüfung warnt, wenn ein Typ nicht zum Feldbus der Kamera passt.
- Byte 0 landet bei Input-Assembly-Byte 288 auf EtherNet/IP und bei Byte 0 des User-Results-Moduls auf PROFINET. Der Rest des Bereichs wird auf null gesetzt
packwirft einenRangeError, wenn ein Wert nicht in sein Feld passt. Testen Sie mit einem fehlerhaften Teil, bevor Sie speichernunpack(layout, bytes)liest Bytes zurück, undcrc(bytes, "crc16-modbus" | "crc32")berechnet eine Prüfsumme
Wenn etwas schiefgeht
Wenn inspect eine Exception wirft, die Zeit überschreitet, den Speicher überschreitet (8 MiB) oder etwas zurückgibt, das die Kamera nicht akzeptieren kann (etwa eine Begründung über 64 Zeichen oder judgment: "PASS"):
- das Teil ist Nicht geprüft
- die SPS User Results werden auf null gesetzt
- nichts, was es zurückgegeben hat (Begründung, Metadaten, Tags), wird verwendet
- der Fehler wird mit der Aufnahme gespeichert, sodass Sie ihn in der Library sehen können
Werte, die auf Modulebene gehalten werden, bestehen nur bis zum erneuten Laden des Rezepts, zum Beispiel nach einem Speichern. Zählen Sie keine Teile und führen Sie keinen Verlauf in einem Recipe-Skript. Verwenden Sie das Kameraskript, das den Status zwischen Ereignissen beibehält.
Was ein Recipe-Skript nicht kann
- Kein Netzwerk, keine Timer und kein Warten: Es gibt kein
fetch,setTimeout,importodereval, undinspectkann nichtasyncsein - Es kann das Bild selbst nicht sehen, nur die Ergebnisse der Tools
- Es liest die Außenwelt nur über
inputund Variablen
Vorlagen
Die Vorlagen-Galerie enthält 14 funktionierende Skripte, gruppiert nach Aufgabe. Wählen Sie eines aus, füllen Sie das Tool oder die Variable aus, die es verwendet, und Vorlage einfügen.

| Gruppe | Vorlagen |
|---|---|
| Pass oder Fail entscheiden | Pass wenn genügend Regionen bestehen · Seriennummer stimmt mit dem OCR-Text überein · Barcode entspricht einer Variablen · Anzahl innerhalb einer Toleranz einer Variablen |
| Wählen, wann geprüft wird | Andere Teiletypen überspringen · Überspringen, wenn eine Variable fehlt oder veraltet ist |
| Daten an die SPS senden | Anzahl als 16-Bit-Zahl senden · Region-Pass/Fail-Flags packen · Einen Ergebniscode für jedes Tool senden |
| Ergebnis erklären | Das Tool benennen, das fehlgeschlagen ist · Die Anzahl in die Begründung aufnehmen |
| Aufnahmen beschriften | Metadaten und ein Review-Tag hinzufügen · Grenzfälle zur Überprüfung taggen · Eine Variable mit jeder Aufnahme speichern |
Test und Verlauf
- Test führt den Entwurf auf einem Live-Trigger aus oder auf gespeicherten Aufnahmen: die neueste, die letzten N (bis zu 500), ein Library-Filter oder Aufnahmenummern. Es zeigt, wo die Beurteilung des Entwurfs von der Beurteilung abweicht, die jede Aufnahme aufgezeichnet hat, sodass Sie sehen, was er entschieden hätte, bevor er live geht
- Verlauf behält Ihre letzten 20 gespeicherten Versionen
Schreiben Sie das Skript, während der Beurteilungsschritt noch auf die Regeln steht, und verwenden Sie Test auf gespeicherten Aufnahmen, um seine Beurteilung mit dem Aufgezeichneten zu vergleichen. Wechseln Sie erst dann auf das Recipe-Skript, wenn sie dort abweichen, wo Sie es möchten.
Wie es weitergeht
- Kameraskript, für alles, was das Netzwerk oder Speicher über Teile hinweg benötigt
- Variablen
- Schritt 5: Beurteilung
- SPS-Handshakes, für den Fall, dass die SPS User Results liest