Werkspur Docs Zur Website

Trigger

Was ist das

Ein Trigger löst eine bestehende Aktion aus, ohne dass ein Bediener sie anstößt. Es gibt fünf Arten. Ein schedule-Trigger läuft nach einem Cron-Zeitplan mit fünf Feldern. Ein event-Trigger reagiert auf ein Ereignis im System, wahlweise mit einer zusätzlichen Bedingung. Ein webhook-Trigger wartet auf einen Aufruf von außen: Ein externes System ruft POST /api/hooks/{name} auf. Ein signal-Trigger reagiert auf einen Telemetrie-Wert einer Maschine. Ein file-Trigger reagiert auf eine neue Datei in einem überwachten Ordner.

Jeder Lauf eines Triggers ist im Audit-Protokoll nachvollziehbar, als Systemakteur trigger:<name>. So lässt sich auch ein automatisch ausgelöster Lauf noch einer Ursache zuordnen.

Wann einsetzen

Anatomie der Definition

Eine Trigger-Definition ist ein flaches JSON-Objekt:

Ruft ein externes System den Webhook ohne den passenden Bearer-Header oder mit einem falschen Wert auf, lehnt WERKSPUR den Aufruf ab. Ein Aufruf ohne gültiges Secret läuft nie durch.

Beispiele

Der erste Trigger stammt aus der gebündelten Beispielkonfiguration, die beiden anderen sind Definitionen zum Nachbauen.

fertigmeldung-trigger trigger
{
  "name": "fertigmeldung-trigger",
  "summary": "Meldet jedes fertige Los automatisch an das ERP.",
  "type": "event",
  "match": {
    "event_type": "StepCompleted",
    "condition": {
      "and": [
        {
          "cmp": {
            "left": {
              "param": "data.done"
            },
            "op": "eq",
            "right": true
          }
        },
        {
          "cmp": {
            "left": {
              "param": "data.qty_good"
            },
            "op": "gt",
            "right": 0
          }
        }
      ]
    }
  },
  "action": "fertigmeldung",
  "inputs": {
    "lot": "${event.data.lot}",
    "order": "${event.data.order_number}",
    "qty": "${event.data.qty_good}"
  },
  "run_as": "operator",
  "enabled": true
}
Mit dem Assistenten
Lege einen Trigger an, der nach dem letzten Schritt automatisch die Fertigmeldung schickt.

Ein event-Trigger auf StepCompleted. Die Bedingung verlangt data.done == true und zusätzlich data.qty_good > 0: Ein Los, das mit Ausschuss endet (qty_good gleich null), gilt zwar auch als `done`, soll aber keine Fertigmeldung auslösen. Der Trigger ruft die Aktion fertigmeldung auf und übergibt Los, Auftrag und Menge aus den Ereignisdaten.

nachtabschluss trigger
{
  "name": "nachtabschluss",
  "summary": "Schließt jede Nacht alle noch offenen Chargen ab",
  "type": "schedule",
  "schedule": "0 2 * * *",
  "action": "chargen-abschliessen",
  "run_as": "planner",
  "enabled": true
}
Mit dem Assistenten
Baue einen nächtlichen Trigger, der offene Lose schließt.

Ein schedule-Trigger mit dem Cron-Ausdruck 0 2 * * *, läuft also jede Nacht um zwei Uhr. Er ruft eine Aktion auf, die jedes noch offene Los abschließt und den Abschluss an ein Zielsystem meldet.

erp-auftrag-webhook trigger
{
  "name": "erp-auftrag-webhook",
  "summary": "Externes System stößt die Fertigmeldung eines Loses an",
  "type": "webhook",
  "webhook": {
    "secret": "erp-webhook-secret"
  },
  "action": "fertigmeldung",
  "inputs": {
    "lot": "${body.lot}",
    "order": "${body.order_number}",
    "qty": "${body.qty}"
  },
  "run_as": "planner",
  "enabled": true
}
Mit dem Assistenten
Ich brauche einen Webhook, über den ein externes System die Fertigmeldung eines Loses anstößt.

Ein webhook-Trigger. webhook.secret verweist auf ein Secret nur über dessen Namen, nie über den Wert selbst. Die Aktion fertigmeldung braucht drei Parameter, lot, order und qty; inputs liest deshalb alle drei aus dem Body des HTTP-Requests, ${body.lot}, ${body.order_number} und ${body.qty}. Fehlt einer davon in den inputs, scheitert jeder Aufruf des Webhooks.

Mit dem Assistenten arbeiten

Jedes Beispiel oben zeigt den Prompt, mit dem Sie denselben Trigger über den Assistenten anlegen lassen können, mit type, schedule oder match oder webhook, der Zuordnung der inputs und einer passenden run_as-Rolle. Besonders bei einem Webhook-Trigger erfindet der Assistent das Secret nie selbst: Er referenziert nur einen bereits im Secret-Speicher vorhandenen Namen. Wie der Assistent grundsätzlich arbeitet, beschreibt das Kapitel Der KI-Assistent.

Fallstricke

Signal-Trigger

Ein signal-Trigger beobachtet einen einzelnen Telemetrie-Wert einer Maschine und löst eine bestehende Aktion aus, sobald der Wert eine Bedingung erfüllt. Der beobachtete Tag muss eine vorhandene Telemetrie-Bindung dieser Maschine sein, über OPC UA oder Modbus. Jeder Signal-Trigger überwacht genau einen Tag genau einer Maschine.

Es gibt drei Bedingungsarten.

Die Boolesche Flanke feuert im Moment des Übergangs. Sie wählen steigend, fallend oder beide. Ein Trigger auf die steigende Flanke eines Fertig-Bits feuert einmal, sobald das Bit von 0 auf 1 wechselt.

Der Schwellwert feuert, wenn der Wert eine Grenze überschreitet oder unterschreitet. Eine Hysterese verhindert wiederholtes Feuern am Rand. Bei Wert 80, wieder scharf ab 75 feuert der Trigger, sobald der Wert 80 überschreitet, und wird erst wieder scharf, wenn der Wert unter 75 fällt. Ohne eigenen Wert liegt der Punkt zum erneuten Scharfstellen auf dem Feuerwert. Optional verlangt „muss anliegen (Sekunden)“, dass der Wert die Grenze für eine Haltezeit überschreitet, bevor der Trigger feuert.

Wert geändert feuert bei jedem Unterschied zum vorherigen Wert. Das funktioniert auch für Zeichenketten, etwa einen gescannten Barcode. Denselben Wert zweimal hintereinander sieht diese Bedingung nicht.

Nach dem Start, nach einer Änderung der Definition und nach einer wiederhergestellten Verbindung setzt der erste Wert nur den Zustand. In diesem Moment feuert nichts.

Schreiben Sie in der SPS zuerst die Nutzdaten und zuletzt den auslösenden Tag. Legen Sie also erst den Barcode ab und erhöhen Sie danach den Scan-Zähler. Feuern Sie auf einen Scan-Zähler oder ein Umschalt-Bit, nie auf den Barcode selbst. Denselben Barcode zweimal hintereinander sieht die Bedingung „Wert geändert“ nicht, ein Zähler dagegen ändert sich bei jedem Scan.

In den inputs der Aktion steht der auslösende Wert als ${signal.value} bereit. Über ${tags.<name>} erreichen Sie die übrigen aktuellen Tag-Werte derselben Maschine, etwa ${tags.barcode} für den zuletzt abgelegten Barcode.

Scheitert ein Feuern, erscheint der Lauf in der Lauf-Liste des Triggers. Einen erneuten Versuch gibt es nicht.

Datei-Trigger

Ein file-Trigger überwacht einen Unterordner des Datei-Eingangs. Jede neue Datei in diesem Ordner löst die hinterlegte Aktion einmal aus. So kommt auch ein Vorsystem ohne eigene Schnittstelle an WERKSPUR heran: Es legt eine Datei ab, den Rest übernimmt die Aktion.

Der Datei-Eingang ist ein Verzeichnis auf dem Server, das der Compose-Stack in die Anwendung einhängt. FOUNDRY_INBOX_DIR in deploy/.env nennt dieses Verzeichnis, standardmäßig ./inbox. Die Anwendung läuft nicht als root. Das Verzeichnis muss deshalb für die Benutzer-ID 10001 beschreibbar sein, sonst kann WERKSPUR die abgelegten Dateien weder verschieben noch aufräumen.

Im Trigger-Editor wählen Sie als Art „Datei“ und tragen zwei Werte ein: den Ordner im Eingang, etwa druckauftraege, und ein Dateimuster, etwa *.pdf. Bleibt das Muster leer, gilt jede Datei. Der Ordner darf verschachtelt sein, etwa werk1/druckauftraege, muss aber innerhalb des Eingangs bleiben. Die Namen done, error und processing sind für den Trigger reserviert und dürfen im Ordnerpfad nicht vorkommen. Zwei eingeschaltete Datei-Trigger dürfen nicht denselben Ordner überwachen; WERKSPUR lehnt die zweite Definition ab.

Der Weg einer Datei führt über drei Ordner. Der Trigger sieht in kurzen Abständen im überwachten Ordner nach und greift eine Datei erst auf, wenn Größe und Änderungszeitpunkt seit dem vorherigen Durchgang gleich geblieben sind. Eine Datei, die gerade geschrieben wird, wartet er auf diese Weise ab. Danach verschiebt er sie nach processing/, ruft die Aktion auf und legt sie anschließend in done/ ab. Scheitert die Aktion, landet die Datei stattdessen in error/. Alle drei Ordner legt WERKSPUR selbst im überwachten Ordner an.

Einen automatischen zweiten Versuch gibt es nicht. Eine Datei aus error/ wiederholen Sie, indem Sie sie erneut in den überwachten Ordner legen. Scheitert ein Lauf, nennt die Fehlermeldung in der Lauf-Liste des Triggers den Dateinamen.

FOUNDRY_INBOX_RETENTION_DAYS legt fest, wie alt eine Datei in done/ oder error/ werden darf, bevor WERKSPUR sie löscht, standardmäßig 30 Tage. Maßgeblich ist der Änderungszeitpunkt der Datei selbst, nicht der Zeitpunkt der Verarbeitung. Eine Datei, die mit einem alten Zeitstempel ankommt, kann deshalb schon beim nächsten Aufräumen gelöscht werden. Der Wert 0 behält sie unbegrenzt. Dateien im überwachten Ordner selbst und in processing/ werden davon nie gelöscht.

In den inputs der Aktion stehen vier Werte der aufgegriffenen Datei bereit:

Ein Platzhalter mit einem anderen Feldnamen lässt den Lauf scheitern, und die Datei wandert nach error/.

Das folgende Beispiel schickt jedes PDF aus dem Ordner druckauftraege an ein Drucksystem. Zuerst der Trigger (kein lauffähiges Beispiel, nur die Form):

{
  "name": "druckauftraege",
  "summary": "PDFs aus dem Datei-Eingang an das Drucksystem schicken.",
  "type": "file",
  "file": {"dir": "druckauftraege", "pattern": "*.pdf"},
  "action": "druckauftrag-senden",
  "inputs": {"datei": "${file.path}"},
  "run_as": "operator",
  "enabled": true
}

Die Aktion druckauftrag-senden hat einen Param datei und einen einzigen Schritt. Das Kommando file.send überträgt die Bytes der Datei unverändert an ein registriertes Zielsystem:

{
  "command": "file.send",
  "bind": {
    "dest": {"literal": "drucksystem"},
    "method": {"literal": "POST"},
    "path": {"literal": "/print"},
    "file": {"param": "datei"}
  },
  "no_compensation": "Ein abgeschickter Druckauftrag lässt sich nicht zurückholen."
}

file.send nimmt nur Pfade unterhalb des Datei-Eingangs an. Jeden anderen Pfad lehnt es ab, bevor es etwas sendet.

Drei Punkte für den Betrieb:

Wie eine Aktion selbst aufgebaut ist, zeigt das Kapitel Aktionen. Wie ein Zielsystem eine solche Fertigmeldung entgegennimmt, zeigt das Kapitel Zielsysteme. Eingehende Queue-Ereignisse beschreibt AMQP-Listener. Webhook-Bearer und Sitzungstoken grenzt API & Authentifizierung voneinander ab. Wie eine Ansicht Daten aus einer gespeicherten Abfrage anzeigt, beschreibt Ansichten. Wie eine gespeicherte Abfrage selbst funktioniert, erklärt Gespeicherte Abfragen.