DOCUMENTACIÓN CON IA
¿Qué desea saber?
Recipe Script
Un recipe script es un fragmento corto de JavaScript que se ejecuta después de las herramientas en cada Inspección de una Receta. Puede:
- decidir aprobado o rechazado con su propia lógica, e indicar el motivo
- escribir sus propios bytes para los User Results del PLC
- guardar metadata y etiquetas con la captura, para que pueda encontrarla en la Biblioteca
Cada Receta tiene como máximo un script, y se exporta junto con la Receta.
Abrir el editor
En el paso Veredicto de la Receta, desplácese hasta Recipe script y haga clic en Open script editor.

En la parte superior del paso Veredicto elige qué decide el veredicto: las reglas o el recipe script. Las reglas siempre se ejecutan, y el script ve su veredicto. Si deja la configuración en las reglas, el script no puede cambiar el aprobado o rechazado, pero su motivo, metadata, etiquetas y bytes para el PLC aún se aplican. Esa es una forma segura de empezar: añada un script para el motivo y los bytes, y mantenga las reglas al mando.

Cómo se ejecuta
Trigger → Capture and tools → Pass/fail rules → inspect(input) → Verdict, PLC User Results, Library, MQTT
El script exporta una función, inspect(input). La cámara la llama en cada Inspección de la Receta, después de las herramientas y las reglas. La línea la espera, por lo que debe ser síncrona y rápida: tiene 25 ms por defecto, hasta 200 ms en las Configuraciones del script, y su tiempo se suma al tiempo de ciclo.
input contiene todo lo recopilado hasta el momento. Es de solo lectura:
| Campo | Qué es |
|---|---|
tools | El resultado de cada herramienta, en el orden en que se ejecutaron |
tools_by_name | Los mismos resultados, pero por nombre de herramienta |
rules | El veredicto de las reglas: judgment, pass, not_inspected |
vars | Sus variables por nombre. Una variable sin valor es null |
vars_info | Para cada variable: received_at, age_ms y source |
recipe | id, uuid y name |
trigger | id, source (por ejemplo plc, gpio, http, manual) y metadata |
Cada resultado de herramienta tiene name, type, judgment, pass, score, plc_slot, execute_ms, error, skipped_by, y un objeto detail cuya forma depende de la herramienta. Verifique type antes de leer detail, por ejemplo ai_fast_classifier (con detail.regions), ai_ocr (con detail.fields), ai_counting (con detail.count) o classical.barcode (con detail.data).
Lo que devuelve
Cada campo es opcional. Un campo que omita mantiene el comportamiento normal de la cámara, por lo que un script puede establecer solo el motivo y dejar el veredicto a las reglas. No devuelva nada para no cambiar nada.
| Campo | Significado | Límite |
|---|---|---|
judgment | "pass", "fail" o "not_inspected" (true, false y null significan lo mismo). Se usa solo cuando el paso Veredicto está configurado en el recipe script | |
reason | Texto mostrado en la Biblioteca y enviado en los mensajes de resultados (MQTT, HTTP API, camera script) | 64 caracteres |
plc_user_results | Bytes para los User Results del PLC, generalmente construidos con pack() | El tamaño configurado de User Results |
metadata | Pares clave-valor guardados con la captura y mostrados en los detalles de la Biblioteca. Las claves son letras, dígitos y guiones bajos, comenzando con una letra; los valores son texto, números o true/false | 32 claves, valores de texto de hasta 256 caracteres |
tags | Etiquetas mostradas como chips en la Biblioteca, donde puede filtrar por ellas | 16 etiquetas, 32 caracteres cada una |
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" };
}
Pruébelo
Área de pruebas del script de receta
Cambia la pieza, edita el script, presiona Ejecutar. El script recibe la misma entrada que la cámara pasa a inspect() y se ejecuta bajo las mismas reglas.
Una herramienta de Clasificación AI con 10 regiones, una por pin. Haz clic en un pin para invertirlo.
Mostrar el objeto de entrada
{
"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"
}
}
}
}Presiona Ejecutar para ver con qué terminaría esta inspección.
Una simulación en tu navegador. En la cámara, usa Probar en el editor de scripts para ejecutar el borrador sobre capturas reales antes de guardar.
Escribir bytes para el PLC
Devuelva plc_user_results, construido con pack(layout, values). El PLC lo lee con el resultado, antes del flanco Inspection Completed.
Describa los bytes una vez como un layout: una lista ordenada de campos { name, type }.
| Tipo | 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 con count | Un bit por valor, el primer valor en el bit más bajo |
ascii o utf8 con length | Texto, rellenado o (con truncate: true) recortado a la longitud |
bytes con length | Bytes sin procesar |
pad con length | Bytes en cero, para omitir un espacio |
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 }) };
}
Cada tipo de varios bytes nombra su propio orden de bytes, y la cámara nunca intercambia bytes por usted. Use los tipos le en EtherNet/IP y los tipos be en PROFINET. La verificación del script advierte cuando un tipo no coincide con el bus de campo de la cámara.
- El byte 0 cae en el byte 288 del input assembly en EtherNet/IP, y en el byte 0 del módulo User Results en PROFINET. El resto de la región se pone en cero
packlanza unRangeErrorcuando un valor no cabe en su campo. Pruebe con una pieza rechazada antes de guardarunpack(layout, bytes)vuelve a leer los bytes, ycrc(bytes, "crc16-modbus" | "crc32")calcula una suma de verificación
Cuando algo sale mal
Si inspect lanza una excepción, se queda sin tiempo, se queda sin memoria (8 MiB), o devuelve algo que la cámara no puede aceptar (como un motivo de más de 64 caracteres o judgment: "PASS"):
- la pieza queda como No inspeccionada
- los User Results del PLC se ponen en cero
- no se usa nada de lo que devolvió (motivo, metadata, etiquetas)
- el error se guarda con la captura, para que pueda verlo en la Biblioteca
Los valores guardados a nivel de módulo duran solo hasta que la Receta se recarga, por ejemplo después de guardar. No cuente piezas ni mantenga historial en un recipe script. Use el camera script, que mantiene el estado entre eventos.
Lo que un recipe script no puede hacer
- No tiene red, ni temporizadores, ni esperas: no hay
fetch,setTimeout,importnieval, yinspectno puede serasync - No puede ver la Imagen en sí, solo los resultados de las herramientas
- Lee el mundo exterior solo a través de
inputy las variables
Plantillas
La galería de Plantillas tiene 14 scripts funcionales, agrupados por tarea. Elija uno, complete la herramienta o variable que utiliza, y Insert template.

| Grupo | Plantillas |
|---|---|
| Decidir aprobado o rechazado | Aprobar cuando suficientes regiones aprueban · El número de serie coincide con el texto OCR · El código es igual a una variable · Conteo dentro de una tolerancia respecto a una variable |
| Elegir cuándo inspeccionar | Omitir otros tipos de pieza · Omitir cuando una variable falta o está desactualizada |
| Enviar datos al PLC | Enviar el conteo como un número de 16 bits · Empaquetar banderas de aprobado/rechazado de regiones · Enviar un código de resultado por cada herramienta |
| Explicar el resultado | Nombrar la herramienta que falló · Poner el conteo en el motivo |
| Etiquetar capturas | Añadir metadata y una etiqueta de revisión · Etiquetar casos límite para revisión · Guardar una variable con cada captura |
Prueba e Historial
- Test ejecuta el borrador en un Disparo en vivo, o en capturas almacenadas: la más reciente, las últimas N (hasta 500), un filtro de la Biblioteca, o números de captura. Muestra dónde el veredicto del borrador difiere del veredicto que cada captura registró, para que vea qué habría decidido antes de ponerlo en producción
- History conserva sus últimas 20 versiones guardadas
Escriba el script con el paso Veredicto aún en las reglas, y use Test en capturas almacenadas para comparar su veredicto con lo registrado. Cambie a el recipe script solo cuando no coincidan donde usted desee.
A dónde ir después
- Camera script, para cualquier cosa que necesite la red o memoria entre piezas
- Variables
- Paso 5: Veredicto
- PLC Handshakes, para cuando el PLC lee los User Results