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

Oben im Beurteilungsschritt wählen Sie, was die Entscheidung trifft: die Regeln oder das Recipe Script. Die Regeln laufen immer, und das Script sieht deren Beurteilung. Wenn Sie die Einstellung auf die Regeln belassen, kann das Script Pass oder Fail nicht ändern, aber seine Begründung, Metadaten, Tags und SPS-Bytes gelten trotzdem. Das ist ein sicherer Einstieg: Fügen Sie ein Script 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 Script 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: standardmäßig stehen 25 ms zur Verfügung, bis zu 200 ms in den Settings des Scripts, und ihre Zeit wird zur Zykluszeit addiert.
input enthält alles bisher Ermittelte. Es ist schreibgeschützt:
| Feld | Was es ist |
|---|---|
tools | Das Ergebnis jedes Tools, in der Reihenfolge, in der die Tools ausgeführt wurden |
tools_by_name | Dieselben Ergebnisse nach Tool-Name |
rules | Die Beurteilung der Regeln: judgment, pass, not_inspected |
vars | Ihre Variablen nach Name. 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 Tool-Ergebnis 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 Script 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 bedeuten dasselbe). Wird nur verwendet, wenn der Beurteilungsschritt auf das Recipe Script eingestellt ist | |
reason | Text, der in der Library angezeigt und in Ergebnisnachrichten gesendet wird (MQTT, HTTP API, Camera Script) | 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 deren Library-Details angezeigt werden. Schlüssel bestehen aus Buchstaben, Ziffern und Unterstrichen und beginnen 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 und 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" };
}
Probieren Sie es aus
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 diese 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 die Länge gekürzt |
bytes mit length | Rohbytes |
pad mit length | Null-Bytes, 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 die Bytes niemals für Sie. Verwenden Sie die le-Typen bei EtherNet/IP und die be-Typen bei PROFINET. Die Script-Prü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 mit Nullen aufgefüllt
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 einen Fehler wirft, die Zeit überschreitet, den Speicher überschreitet (8 MiB) oder etwas zurückgibt, das die Kamera nicht akzeptieren kann (zum Beispiel eine Begründung über 64 Zeichen oder judgment: "PASS"):
- wird das Teil als Not inspected markiert
- werden die SPS User Results mit Nullen gefüllt
- wird nichts von dem Zurückgegebenen (Begründung, Metadaten, Tags) verwendet
- wird der Fehler 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 dem Speichern. Zählen Sie keine Teile und führen Sie keinen Verlauf in einem Recipe Script. Verwenden Sie das Camera Script, das den Zustand zwischen Ereignissen behält.
Was ein Recipe Script 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 Templates-Galerie enthält 14 funktionierende Scripts, gruppiert nach Aufgabe. Wählen Sie eines, füllen Sie das Tool oder die Variable aus, die es verwendet, und klicken Sie auf Insert template.

| 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 |
| Entscheiden, wann geprüft wird | Andere Teiletypen überspringen · Überspringen, wenn eine Variable fehlt oder veraltet ist |
| Daten an die SPS senden | Die Anzahl als 16-Bit-Zahl senden · Regions-Pass/Fail-Flags packen · Einen Ergebniscode für jedes Tool senden |
| Das Ergebnis erklären | Das fehlgeschlagene Tool benennen · 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 mit einem Live-Trigger aus oder mit gespeicherten Aufnahmen: der neuesten, den letzten N (bis zu 500), einem Library-Filter oder Aufnahmenummern. Es zeigt, wo sich die Beurteilung des Entwurfs von der Beurteilung unterscheidet, die jede Aufnahme aufgezeichnet hat, sodass Sie sehen, wie entschieden worden wäre, bevor es in den Produktivbetrieb geht
- History bewahrt Ihre letzten 20 gespeicherten Versionen auf
Schreiben Sie das Script, während der Beurteilungsschritt noch auf die Regeln eingestellt ist, und verwenden Sie Test mit gespeicherten Aufnahmen, um seine Beurteilung mit dem Aufgezeichneten zu vergleichen. Wechseln Sie erst dann zu das Recipe Script, wenn sie dort abweichen, wo Sie es möchten.
Wie es weitergeht
- Camera Script, für alles, was Netzwerk oder Speicher über mehrere Teile hinweg benötigt
- Variablen
- Schritt 5: Beurteilung
- SPS-Handshakes, wenn die SPS User Results liest