Scripts de automatización
Un script de automatización es código JavaScript que abre, modifica y guarda dibujos sin la ventana de la aplicación: para un sistema de pedidos o una base de datos que crea un dibujo por cada pedido, un trabajo por lotes que convierte una carpeta de dibujos en archivos DXF, o una exportación nocturna a las mesas de corte. Usa la misma API de dibujo que las extensiones y añade funciones para abrir y guardar dibujos, ejecutar los diseños paramétricos de la biblioteca, exportarlos y leer y escribir archivos.
// orders.js: a box for each order, as a PDF for the customer and a DXF for the sample table
const box = runDesign("Packaging › FEFCO 0201 Regular slotted container", { L: 400, W: 300, D: 250 });
box.setNote("order", args[0]);
box.export("pdf", "out/" + args[0] + ".pdf");
box.export("dxf", "out/" + args[0] + ".dxf");
box.save("out/" + args[0] + ".piq");
log(args[0], "blank", box.info().totals.width, "×", box.info().totals.height);
Ejecutar un script
Desde la línea de comandos, con el programa de la aplicación y la palabra run:
PiQ run orders.js A-1017
PiQ run --folder D:\Orders --timeout 120 orders.js A-1017
Las opciones van antes del script; cada palabra que va después se pasa al script en args (args[0] es
"A-1017"). Lo que el script registra se escribe en la salida, y el motivo de un fallo, en la salida de errores. El
código de salida es 0 cuando se ejecutó hasta el final, 1 cuando falló y 2 cuando la línea de comandos es incorrecta,
para que el sistema que lo ejecuta pueda saberlo. No se abre ninguna ventana.
| Opción | Significado |
|---|---|
--folder DIR |
Una carpeta que el script puede leer y escribir, junto con las que contiene; indíquela varias veces para varias. La primera es su carpeta de trabajo: las rutas que no son completas se leen desde ella. Sin ninguna, la carpeta actual y la del propio script. |
--extensions DIR |
Una carpeta de extensiones cuyos diseños de biblioteca (Parametric), posprocesadores, informes, extensiones de guardado y perfiles de máquina (Profiles) usa el script; sin ella, los suyos y los de la aplicación. |
--allow-host HOST |
Un servidor web desde el que se pueden abrir dibujos (example.com, o *.example.com para los que dependen de él). Ninguno salvo que se indique. |
--timeout SECONDS |
El tiempo máximo de ejecución: 600 segundos salvo que se indique. |
--no-save-extensions |
Guarda los dibujos sin ejecutar las extensiones de guardado. |
--help |
Muestra todo esto. |
Desde la aplicación: Archivo › Extensiones › Ejecutar script… pide el script y sus argumentos (separados por
espacios, entre comillas dobles si alguno contiene un espacio) y lo ejecuta en segundo plano. Puede usar los archivos
de su propia carpeta y de las que contiene. Lo que registra va a la ventana Interactiva del dibujo abierto, y cuando
termina se indica cómo ha ido. show(drawing) abre en la aplicación un dibujo que ha creado, para verlo o seguir
trabajando en él. Ponga sus scripts donde guarda los archivos con los que trabajan; la aplicación incluye un ejemplo en
su carpeta Extensions\Automation.
Guardar y exportar requieren una licencia que se pueda usar, igual que en la aplicación: sin ella, el script puede
abrir y leer dibujos, y save y export fallan indicando el motivo.
Dibujos
| Función | Significado |
|---|---|
openDrawing(path, values) |
Abre un archivo de dibujo. values (si se indica) sustituye a los valores propios del archivo para sus variables al leerlo, como hace Ejecutar paramétrico: openDrawing("tray.piq", { L: 300, BOARD: "B flute" }). |
openDrawing(url, values) |
Abre un dibujo de la web, de un servidor permitido (--allow-host). |
openDrawing(text, values) |
Texto de dibujo (el lenguaje de dibujo, con algún salto de línea): crea un dibujo a partir de él. |
openDrawing({path, url, text, values, units, name}) |
Lo mismo, indicado por completo: units, "mm" o "in" (si no, lo que diga el archivo); name, su nombre. |
newDrawing({units, industry, name}) |
Un dibujo nuevo y vacío: en "mm" (salvo que se indique otra cosa), para un sector ("Packaging", "SheetMetal" …) si se indica. |
runDesign(name, values) |
Ejecuta un diseño de la biblioteca con unos valores, como lo ejecuta Archivo › Ejecutar paramétrico, para el sector de su carpeta: runDesign("Packaging › Sleeve", { L: 200 }), o simplemente runDesign("Sleeve") si ningún otro diseño tiene ese nombre. |
designs() |
Los diseños de la biblioteca: cada uno {name, industry, description}. |
designInputs(name) |
Lo que pide un diseño: cada dato {name, label, kind, value, choices}; kind es "number", "text", "toggle" o "choice". |
use(drawing) |
Convierte un dibujo en el dibujo actual (véase más abajo). |
currentDrawing() |
El dibujo actual, o null. |
show(drawing) |
En la aplicación, abre el dibujo en una ventana propia (sin guardar); desde la línea de comandos, no hace nada. |
batch(items, fn) |
fn(item, index) para cada elemento (la ruta de un archivo, una fila de un CSV …). Si uno lanza un error, se indica en el registro y los demás continúan; los dibujos abiertos en una llamada se cierran después de ella. Devuelve una lista de {item, ok, result, error}. |
El valor de una opción de lista es el nombre del elemento ("B flute") o su posición en la lista, desde 0. Se rechaza
una variable que el archivo no tiene.
El dibujo actual
La API de dibujo (vars.L, newPoint, line, circle, command("…"), drawingInfo(),
setNote, classify …) trabaja sobre el dibujo actual: el último abierto o creado, o el que eligió
use(drawing). Los cambios se hacen como los hace la ventana Interactiva, así que lo que se dibuja es paramétrico.
const panel = newDrawing({ units: "in", industry: "SignMaking", name: "Panel" });
setVariable("W", 48);
setVariable("H", 24);
const a = newPoint("[0,0]");
const b = newPoint("[W,0]");
const c = newPoint("[W,H]");
const d = newPoint("[0,H]");
polyline([a, b, c, d], true);
panel.save("panel.piq");
Las funciones de un dibujo
openDrawing, newDrawing y runDesign devuelven un dibujo, con estas funciones:
| Función | Significado |
|---|---|
name, path |
Su nombre y su archivo (null hasta que tenga uno). |
variable("L") |
El valor de una variable. |
variables() |
Sus variables (no las ocultas), por nombre, calculadas. |
inputs() |
Sus variables con etiqueta, tal como las da designInputs. |
setVariable("L", value), setVariables({ L: 300, W: "L/2" }) |
Establece variables y vuelve a calcular el dibujo. Un número, true o false; texto para una variable de texto; un elemento de una opción de lista; si no, una expresión ("L/2"). Se conserva su etiqueta. |
evaluate("…") |
Una expresión calculada en él: evaluate("DISTANCE(P0,P2)"). |
run("…") |
Ejecuta en él instrucciones del lenguaje de dibujo, una por línea: run("FILLET(@1,@2,5)"). |
info() |
Todo lo que se sabe de él, tal como lo da drawingInfo(): medidas, totales, capas, imposiciones … |
notes(), setNote(name, value), classification(), classify(…) |
Sus notas y lo que es, como en la API de dibujo. |
regenerate() |
Lo vuelve a calcular (ya se hace tras cada cambio): lo que falle en uno de sus bloques (IF, FOR …) lanza un error. |
check() |
Lo que ha encontrado cada regla de diseño: cada hallazgo {rule, severity, message, elements, at}. |
report(name, options, path) |
Un informe: {title, summary, tables, notes, text, csv}, escrito en path si se indica (.csv, .xlsx, .ods, .html, .pdf, .docx, .odt, .md, .json; si no, texto). |
export(format, path, options) |
Lo exporta (véase más abajo): {path, format, extension, size, warnings}. |
export(path, options) |
Lo exporta en el formato que indica la extensión del archivo. |
sendTo(profile, path) |
Lo exporta con un perfil de máquina (su id o su nombre), como hace Archivo › Enviar con perfil de máquina: su formato, los nombres, colores y plumillas de sus capas, su posprocesador, su patrón de nombre de archivo; en path (una carpeta o un archivo) o, si no, en su propia carpeta. |
save(path) |
Lo guarda como archivo de dibujo (.piq si el nombre no tiene extensión), en su propio archivo si no se indica ninguna ruta; después se ejecutan las extensiones de guardado, como las ejecuta Archivo › Guardar. Devuelve {path, records}: lo que devolvió cada extensión de guardado, {extension, record, error}. |
text() |
El dibujo como texto de dibujo, tal como se guardaría. |
use(), with(fn) |
Lo convierte en el dibujo actual; o llama a fn(drawing) con él como actual y después vuelve a dejar como actual el anterior. |
close() |
Lo cierra: después no se puede usar. |
Exportar
format es el nombre de un formato de exportación, sin distinguir mayúsculas y minúsculas (pdf, svg, eps, ai,
png, jpeg, webp, dxf, gcode, hpgl, cf2, ddes, lightburn, laserSvg, aamaDxf, tiledPdf,
projectorPdf, wrapTemplatePdf, printCutPdf, printCutEps, gpgl, cuttingSvg, matCutterDxf,
matCutterHpgl, dielinePdf, dstv, ifc, bendDxf, step, piq; exportFormats() los enumera), o una
extensión de archivo (jpg, plt, nc, dd3, lbrn2, nc1, stp); null para usar la extensión de la ruta.
Véase Formatos de archivo. Si path es una carpeta (existe, o termina en /), el archivo lleva dentro
de ella el nombre del dibujo. Cada formato se escribe con su configuración habitual; options puede indicar:
| Opción | Significado |
|---|---|
margin |
Espacio alrededor del dibujo, en puntos (PDF, SVG, EPS, AI, imágenes). |
spotColours |
false: sin colores directos para las capas de la línea de troquel. |
textAsOutlines |
true: el texto como contornos. |
width, dpi, quality, transparent |
Imágenes: píxeles de ancho (o dpi), calidad JPEG/WebP, fondo transparente. |
title |
El título que se escribe en el archivo. |
paper, overlap |
El papel (A4, A3, Letter …) y el solape de la impresión en mosaico. |
postProcessor, settings |
Lo escribe en su lugar un posprocesador (por su nombre), con su configuración (el resto, la suya propia): export(null, "out/", { postProcessor: "Router 2", settings: { feed: 1200 } }). |
Archivos
Un script solo lee y escribe archivos en sus carpetas (--folder, o la del script en la aplicación); una ruta que no
es completa se lee desde la primera. Todo lo demás se rechaza.
| Función | Significado |
|---|---|
args |
Las palabras que siguen al nombre del script: una lista de textos. |
readText(path), writeText(path, text), appendText(path, text) |
Un archivo de texto (UTF-8). |
readJson(path), writeJson(path, value) |
Un archivo JSON. |
readCsv(path, { separator }) |
Un archivo CSV, un registro por fila con los nombres de la fila de encabezado; los números, como números. El separador es la coma, el punto y coma o el tabulador, el que más aparezca en el encabezado, salvo que se indique. |
writeCsv(path, rows) |
Registros (objetos: los nombres del primero forman el encabezado) o listas, como un archivo CSV. |
writeSpreadsheet(path, rows) |
Filas como las toma writeCsv, como un libro de Excel (.xlsx, que también abren Numbers y Hojas de cálculo de Google), una hoja de cálculo OpenDocument (.ods, la de LibreOffice) o CSV, según la extensión de la ruta: los números siguen siendo números, el encabezado en negrita. |
listFiles(folder, pattern, all) |
Los archivos de una carpeta ("*.piq"; all: también los de las carpetas que contiene), con rutas completas, en orden. |
exists(path), makeFolder(path) |
Si existe un archivo o una carpeta; crea una carpeta. |
joinPath(a, b, …), baseName(path) |
Une rutas; el nombre de un archivo sin su carpeta ni su extensión. |
log(…), print(…), console.log(…) |
Muestra algo: en la salida o en la ventana Interactiva. Los valores que no son texto se escriben como JSON. |
Las carpetas se crean al escribir archivos en ellas. Un archivo que se vuelve a escribir se sustituye.
Errores
Lo que sale mal (un archivo no permitido o inexistente, una variable que el dibujo no tiene, una instrucción que no
puede ejecutar, un formato que no conoce) es un error de JavaScript, con un mensaje que indica el motivo. Captúrelo con
try … catch para continuar, o deje que detenga el script: se indica con el nombre del script y la línea
(orders.js, line 12: …), y el código de salida es 1. batch captura los de cada elemento.
for (const file of listFiles("in", "*.piq")) {
try {
const d = openDrawing(file);
d.export("dxf", "dxf/");
d.close();
} catch (e) {
log("Not exported:", file, e.message);
}
}
Ejemplo: una caja por cada fila de un archivo CSV
box-sizes.js, en la carpeta Extensions\Automation de la aplicación junto con un box-sizes.csv para probarlo,
crea una caja americana (regular slotted container) por cada fila de medidas de caja (nombre, L, W, D y cartón), la
escribe como PDF y como DXF y la guarda, y escribe made.csv con el tamaño de cada plancha y su longitud de corte
para que el sistema de pedidos lo lea de vuelta:
PiQ run box-sizes.js box-sizes.csv out
const made = batch(readCsv(args[0]), row => {
const values = { L: row.L, W: row.W, D: row.D };
if (row.board) values.T = row.board;
const box = runDesign("Packaging › FEFCO 0201 Regular slotted container", values);
box.export("pdf", joinPath(args[1], row.name + ".pdf"));
box.export("dxf", joinPath(args[1], row.name + ".dxf"));
box.save(joinPath(args[1], row.name + ".piq"));
return box.info().totals;
});
writeCsv(joinPath(args[1], "made.csv"),
made.map(m => ({ name: m.item.name, ok: m.ok, width: m.ok ? m.result.width : "", error: m.error ?? "" })));
Notas
- Un script no tiene ventana y no pregunta nada: lo que un formato preguntaría en la aplicación toma su configuración habitual. Los perfiles de máquina aportan su formato, sus capas, sus nombres de archivo y su posprocesador; las opciones de formato que guarda un perfil (de la página de opciones del formato) todavía no se usan: se usa la configuración habitual del formato.
- El script se ejecuta durante un máximo de diez minutos (
--timeout), sea cual sea el número de instrucciones;DateyMath.random()funcionan como de costumbre. No puede acceder a otros programas, a archivos fuera de sus carpetas ni a la web (salvo para los dibujos abiertos desde un servidor permitido). - Los dibujos que guarda un script indican en su cabecera que los creó él, igual que los de la aplicación.
- Para registrar en una base de datos cada dibujo guardado, escriba una extensión de guardado:
también se ejecuta para los dibujos que guarda un script, y lo que devuelve está en los
recordsdesave.
Véase también: Extensiones, API de dibujo, Ejecutar paramétrico, Formatos de archivo, Perfiles de máquina.