Zum Hauptinhalt springen

Flow (Flow)

🎬 Automate with flows · 39초 · 2026.08 기준 화면

Inhaltsverzeichnis​

Flow-Listenbildschirm

Erste Schritte

Bildschirm-Leitfäden

Nachrichten-/Knoten-Referenz

Beispiele·Muster

Betrieb

Produktionsbetrieb

Fehlerbehebung

Sonstiges


Übersicht​

Flow ist ein Automatisierungsmenü, mit dem Sie die Datenanbindung an externe Systeme (MES/ERP/SCADA usw.) sowie die automatische Erstellung/Aktualisierung von Domänenobjekten (Tag, Anlage, Arbeitsauftrag, Mitarbeiter usw.) als visuellen Graphen definieren. Operatoren können Automatisierungsszenarien ohne Programmierkenntnisse selbst entwerfen, bereitstellen und betreiben.

Über 100 Knotentypen werden per Drag & Drop auf die Canvas platziert und über Wires verbunden, um Datenverarbeitungspipelines zu erstellen.

Pfad: Linkes Menü > Automation > Flow


Lernpfad — Empfohlene Einstiegsreihenfolge nach Rolle​

Dieses Handbuch ist ein umfassender Leitfaden mit über 4.000 Zeilen. Es ist effizient, mit dem Abschnitt zu beginnen, der Ihrer Rolle und Ihrem Ziel entspricht.

👶 Erstbenutzer (ersten Flow innerhalb einer Stunde erstellen)​

  1. Kernkonzepte — 5 Minuten
  2. Erste Schritte — 5 Minuten
  3. End-to-End-Tutorial — 30 Minuten (Schritte 1–10 folgen)
  4. Bildschirmaufbau + Bearbeitungsbildschirm — 10 Minuten
  5. Beispiel-Flows 1·2·3 nachvollziehen — 10 Minuten

→ Erster Flow bereitgestellt. Danach benötigte Knoten im Node-Katalog suchen.

🧑‍🏭 Vor-Ort-Operator (Erstellung von Automatisierungsszenarien)​

  1. Payload-Beispiele nach Trigger — reale Datenstruktur verstehen
  2. Detaillierte Node-Optionsreferenz — häufig verwendete Node-Optionen kennenlernen
  3. Cookbook für Datentransformation — gängige Transformationsmuster kopieren
  4. Katalog der Graph-Muster — Verdrahtungsmuster auswählen
  5. Beispiel-Flows (17종) — fertige Beispiele je Szenario

🛠 Systemadministrator (Betrieb·Tuning·Störungsbehebung)​

  1. Flow-Metriken und Alarme — welche Kennzahlen zu beobachten sind
  2. Was in der Ausführungshistorie zu sehen ist — Diagnoseprotokolle interpretieren
  3. Cluster·HA-Verhalten — Multi-Node-Umgebung verstehen
  4. End-to-End-Trace — problematische Nachrichten verfolgen
  5. Leistungsgrenzen und Tuning + Notfallreaktionsverfahren

🔌 Entwickler·Integrationsingenieur (Anbindung externer Systeme)​

  1. Cookbook für externe Systemintegration — Slack/Teams/Jira/SAP-Beispiele
  2. Flow REST API — Flow programmatisch steuern
  3. Webhook-Trigger — Flow von außen auslösen
  4. OPC/PLC-Industrieintegrationsmuster — Szenarien für den Industriebetrieb
  5. JS-Ausführungsumgebungsspezifikation + Sammlung wiederverwendbarer Skripte

🔐 Sicherheitsverantwortlicher (Audit·Authentifizierung)​

  1. Sicherheit·Umgang mit sensiblen Informationen — Aufbewahrung von Anmeldedaten
  2. Automatische Aktualisierung externer Authentifizierungstoken — Betrieb von OAuth2-Token
  3. Berechtigungen — mögliche Aktionen je Rolle
  4. Audit·Historien-Tracking — Aufbewahrung von Änderungs-/Ausführungshistorie

📚 Schnellreferenz (für bereits erfahrene Benutzer)​

Gesuchte InformationAbschnitt
Node-ID und KurzbeschreibungNode-Katalog
Standardwerte der Node-OptionenDetaillierte Node-Optionsreferenz
JSON-Beispiele für NachrichtenPayload-Beispiele nach Trigger
Direkt verwendbare SkripteSammlung wiederverwendbarer Skripte · Cookbook für Datentransformation
API-Aufruf curlFlow REST API
Interpretation der AusführungshistorieWas in der Ausführungshistorie zu sehen ist
Leitfaden zur FehlerbehebungSchrittweiser Debugging-Leitfaden · Häufig auftretende Probleme
Schnelle OptionsübersichtSchnelle Node-Konfigurationsreferenz

Alle Abschnittslinks sind Anker innerhalb desselben Dokuments. Auch die Stichwortsuche mit Ctrl+F ist wirksam.


Kernkonzepte​

BegriffBeschreibung
Flow (Flow)Ein einzelner Automatisierungs-Workflow, der aus einer Menge von Knoten und Wires (Beziehungen) besteht. Es handelt sich um einen gerichteten Graphen mit Einstiegspunkt, dessen Aktivierung über den Bereitstellen/Aufheben-Schalter gesteuert wird
Node (Node)Eine Einheit, die eine Nachricht empfängt, verarbeitet und an den nächsten Node weiterleitet. Unterteilt in 7 Kategorien (Trigger·Filter·Transformation·Aktion·Externe Anbindung·Ablaufsteuerung·Edge)
Relation (Relation)Das Label des Wires vom Node-Ausgang zum nächsten Node. Der Node bestimmt die Verzweigung direkt durch Labels wie SUCCESS/FAILURE/TRUE/FALSE/MATCH/NO_MATCH/DEFAULT/THROTTLED/EXHAUSTED. Alle Labels sind auf Großbuchstaben standardisiert
Message (Message)Die Payload, die im Flow fließt. Enthält type (Klassifizierung), originator (Subjekt-Entität), data (Inhalt), metadata (Kontext)
Trigger (Trigger)Der Node, der den Startpunkt des Flows bildet. Es gibt drei Arten: Domain-Ereignisse (Tag-Datenpunkt·Alarm·Anlagen-Ereignis usw.), externer Eingang (Webhook·MQTT·externe DB) und Zeit (Schedule)

Erste Schritte​

Am schnellsten machen Sie sich mit Flow in folgenden 4 Schritten vertraut.

  1. Klicken Sie im Listenbildschirm auf die Schaltfläche 새 플로우, um einen leeren Flow zu erstellen (nur Name und Beschreibung eingeben).
  2. Ziehen Sie im Bearbeitungsbildschirm aus der linken Palette nacheinander einen Trigger-Node (z. B. flow_on_tag_alarm) → Filter → Aktion (z. B. flow_send_email) und verbinden Sie die Nodes über Wires.
  3. Klicken Sie auf jeden Node, geben Sie die Optionen im rechten Inspektor ein und überprüfen Sie den Ablauf mit Speichern → Testlauf oben rechts einmal.
  4. Wenn Sie den Schalter Bereitstellen oben aktivieren, wird der Flow bei jedem eingehenden Trigger-Ereignis automatisch ausgeführt; das Ergebnis können Sie im Live-Debug-Panel und im Ausführungshistorie-Bildschirm einsehen.

Zu Verdrahtungsmustern für Automatisierungsszenarien siehe Beispiel-Flows und Anwendungsbeispiele in diesem Dokument. Ein schrittweises Tutorial, das einen echten Flow von Anfang bis Ende erstellt, finden Sie im End-to-End-Tutorial.


End-to-End-Tutorial​

Ein schrittweises Tutorial, in dem ein in der Produktionsumgebung tatsächlich nutzbarer Automatisierungs-Flow von Anfang bis Ende erstellt wird. Szenario: Wenn die Motortemperatur 80 °C überschreitet, automatisch einen dringenden Wartungsauftrag ausstellen und den Verantwortlichen per E-Mail benachrichtigen.

Schritt 1 — Neuen Flow erstellen​

  1. Klicken Sie im linken Menü auf Automation > Flow → Listenbildschirm öffnen
  2. Klicken Sie oben rechts auf die Schaltfläche Neuer Flow
  3. Geben Sie folgende Informationen ein und klicken Sie auf Bestätigen
ElementEingabewert
Name모터 과열 자동 정비 발행
Beschreibung[자동화] 모터 자산의 온도 80°C 초과 시 긴급 정비 작업지시 + 이메일. 담당: ops@example.com

Nach Erstellung des Flows öffnet sich automatisch der Bearbeitungsbildschirm mit leerer Canvas.

Schritt 2 — Trigger-Node platzieren​

Motortemperaturdaten aus einem Anlagen-Telemetrie-Ereignis empfangen.

  1. Kategorie Trigger (Trigger) in der linken Palette aufklappen
  2. Node flow_on_tag_point auf die Canvas ziehen
  3. Node anklicken → folgende Optionen im rechten Inspektor eingeben
OptionWert
Anzeigename태그 포인트 인입
tag_id_patternMOTOR-*.TEMP

Wenn nur der Motortemperatur-Tag mit tag_id_pattern durchgelassen wird, verringert sich der nachfolgende Durchsatz erheblich. Andere Tags werden als SKIPPED behandelt und nicht in den Zähler aufgenommen.

Schritt 3 — Schwellenwertfilter​

Fügen Sie einen Skriptfilter hinzu, damit nur Nachrichten über 80 °C durchgelassen werden.

  1. flow_script_filter aus der Kategorie Filter (Filter) ziehen
  2. Wire vom Ausgangsport des Trigger-Nodes zum Eingangsport des neuen Filter-Nodes verbinden
  3. Im Inspektor Folgendes eingeben
OptionWert
Anzeigename임계값 필터 (80°C 초과)
languageJS
scriptdata.value > 80

Schritt 4 — Domänenänderung (Tag → Anlage)​

Da Alarm und Arbeitsauftrag natürlicherweise auf Anlagenebene ausgestellt werden, wird der Originator der Nachricht vom Tag in die übergeordnete Anlage transformiert.

  1. flow_change_originator aus der Kategorie Transformation (Transform) ziehen
  2. Wire vom TRUE-Ausgang des Filter-Nodes verbinden
  3. Inspektor:
OptionWert
AnzeigenameTag → Asset 변경
entity_typeAsset
id_fieldmetadata.asset_id

metadata.asset_id wird bei Eingang eines Tag-Datenpunkts automatisch befüllt. Fehlt es in der Nachricht, können Sie den Präfix-Teil der Tag-ID (z. B. MOTOR-001.TEMP → MOTOR-001) auch per Skript extrahieren.

Schritt 5 — Arbeitsauftrag ausstellen​

Erstellt automatisch einen dringenden Wartungsauftrag.

  1. flow_create_work_order aus der Kategorie Aktion (Action) — Domain CRUD ziehen
  2. Wire vom SUCCESS-Ausgang des Transformationsnodes verbinden
  3. Inspektor:
OptionWert
Anzeigename긴급 정비 작업지시 생성
asset_id_fieldoriginator.id
order_name_field(statischer Wert) 긴급 점검 — 모터 과열
master_id_field(optional) data.master_id (falls nicht angegeben, automatisch erzeugt)
description_field(statischer Wert) 자동 발행: 임계 온도 초과로 긴급 점검 필요
default_priorityHIGH

Schritt 6 — E-Mail-Benachrichtigung (Erfolgszweig)​

Bei erfolgreicher Ausstellung des Arbeitsauftrags wird der Verantwortliche benachrichtigt.

  1. flow_send_email aus der Kategorie Externe Anbindung (External) ziehen
  2. Wire vom SUCCESS-Ausgang des Arbeitsauftrag-Nodes verbinden
  3. Inspektor:
OptionWert
Anzeigename정비 담당자 이메일
toops@example.com
subject_template[과열 정비] ${originator.id} 작업지시 ${data.work_order_id}
body_template자산 ${originator.id} 의 온도가 ${data.value}°C 로 상승하여 자동으로 긴급 정비가 발행되었습니다.\n작업지시 ID: ${data.work_order_id}

Schritt 7 — Fehlerzweig behandeln​

Auch das Ausstellen des Arbeitsauftrags selbst kann fehlschlagen (z. B. Anlage nicht mehr vorhanden oder Berechtigungsproblem). Sende sofort eine Push-Benachrichtigung an den Operator.

  1. flow_send_push unter Externe Anbindung ziehen
  2. Wire vom FAILURE-Ausgang des Arbeitsauftrag-Nodes verbinden
  3. Inspektor:
OptionWert
title자동화 실패
body_template${originator.id} 정비 자동 발행 실패: ${data.error}

Schritt 8 — Speichern und Testlauf​

  1. Auf die Schaltfläche Speichern oben rechts klicken. Ein automatischer Snapshot wird angelegt, sodass später zurückgerollt werden kann.
  2. Auf die Schaltfläche Testlauf oben rechts klicken → im JSON-Editor Folgendes eingeben → Veröffentlichen
{
"type": "POST_TELEMETRY",
"originator": { "entity_type": "Tag", "id": "MOTOR-001.TEMP" },
"data": { "value": 92.5 },
"metadata": { "ts": 1746247200000, "tag_id": "MOTOR-001.TEMP", "asset_id": "MOTOR-001" }
}

Unten im Dialog wird ✓ JSON OK (type=POST_TELEMETRY) angezeigt → auf Veröffentlichen klicken.

  1. Im Live-Debug-Panel Folgendes prüfen:
    • Trigger-Node leuchtet grün → Nachricht durchlaufen
    • Filter-Node: da 92.5 > 80, Verzweigung nach TRUE
    • Transformations-Node: Originator wird zu Asset/MOTOR-001 geändert
    • Arbeitsauftrag-Node: SUCCESS, data.work_order_id automatisch vergeben
    • E-Mail-Node: Sendeversuch

Schritt 9 — Verifizierung und Bereitstellung​

  1. Im Arbeitsauftrag-Bildschirm prüfen, ob ein neuer Arbeitsauftrag registriert wurde
  2. Prüfen, ob die E-Mail ordnungsgemäß angekommen ist (Testumgebungs-Postfach)
  3. Nochmals mit einer Nachricht unter 80 °C testen (sollte am Filter blockiert werden):
{ "type": "POST_TELEMETRY", "originator": {"entity_type":"Tag","id":"MOTOR-001.TEMP"},
"data": {"value": 70}, "metadata": {"asset_id":"MOTOR-001"} }

Die Verzweigung am Filter-Node ist FALSE, nachfolgende Nodes grau — korrekt.

  1. Nach Verifizierung aller Zweige mit Alle Zähler zurücksetzen das Statistikfenster zurücksetzen
  2. Schalter Bereitstellen oben aktivieren

Ab jetzt wird in der tatsächlichen Produktionsumgebung sofort bei Motortemperaturen über 80 °C automatisch ein Wartungsauftrag ausgestellt und der Verantwortliche per E-Mail benachrichtigt.

Schritt 10 — Betriebsüberwachung​

Es ist sicher, in den ersten 5–10 Minuten nach der Bereitstellung Folgendes zu prüfen.

OrtPrüfpunkt
ListenbildschirmOb die Ausführungsanzahl der betreffenden Flow-Zeile im normalen Bereich zunimmt (nicht ausufernd)
Live-Debug-PanelOb keine Node-Fehler vorliegen
Ausführungshistorie-BildschirmBei fehlgeschlagenen Nachrichten die Ursache in NODE_ERROR prüfen
Empfangene E-MailOb Benachrichtigungen nicht unbeabsichtigt häufig eingehen

Nächste Schritte​

Um diesen Flow weiterzuentwickeln:

  • Retry-Verdrahtung hinzufügen — bei Fehlschlag von E-Mail-/Push-Versand mit Backoff wiederholen (siehe Beispiel 8)
  • Automatische Bandanpassung — Schwellenwert automatisch anhand 6-Stunden-Mittelwert ± 3σ korrigieren (siehe Beispiel 6)
  • Downtime kumulieren — Überhitzungshistorie in Anlagen-Attribut kumulieren (siehe Beispiel 14)
  • Isolierung der Qualitätslinie — bei wiederholter Überhitzung Linie automatisch stoppen (siehe Beispiel 15)

Bildschirmaufbau​

Flow besteht aus folgenden drei Bildschirmen.

BildschirmVerwendung
ListeÜbersicht·Suche·Massenbereitstellung·Import registrierter Flows
BearbeitungNodes über visuelle Canvas platzieren·verbinden·konfigurieren
AusführungshistorieNode-bezogene Ausführungsprotokolle·Timeline abrufen

Listenbildschirm​

Besteht aus dem oberen Such-/Erstellungsbereich und der Flow-Übersichtstabelle.

Werkzeuge oben​

ElementBeschreibung
Statusfilter전체 / 배포 / 해제
Namens-/BeschreibungssucheFlows nach Stichwort filtern
Neuer FlowLeeren Flow erstellen (Name·Beschreibung eingeben)
ImportierenÜber Export erhaltene JSON hochladen, um einen Flow wiederherzustellen
Alle neu bereitstellenAlle aktivierten Flows auf einmal erneut laden
AktualisierenListe erneut abrufen

Übersichtstabelle​

Die Listentabelle ist mit 25 Zeilen pro Seite paginiert; jede Zeile zeigt eine Verarbeitungstrend-Sparkline und ein Fehlerquote-Donut-Diagramm. Der Diagrammstatus bleibt beim Seitenwechsel erhalten.

SpalteBeschreibung
AuswahlCheckbox für Massenbereitstellung·-aufhebung
StatusBadge 배포 / 해제
Flow-IDSequenz-ID im Format FLOW_NNNNN
Name | BeschreibungVom Operator festgelegte Metainformationen
NodesAnzahl enthaltener Nodes
TriggerAnzahl der Trigger-Nodes
AusführungsanzahlKumulierte Nachrichtenverarbeitungszahl
VerarbeitungszeitDurchschnittliche/letzte Node-Verarbeitungszeit
FehlerKumulierte Fehleranzahl
Letzte ÄnderungZeitpunkt der letzten Graph-Speicherung
AktionSchaltflächen 편집 / 삭제

Massenbereitstellung·-aufhebung​

Ausgewählte Flows werden gemeinsam bereitgestellt (aktiviert) oder aufgehoben (deaktiviert). Nur bereitgestellte Flows empfangen Trigger-Ereignisse.

Alle neu bereitstellen​

Die Schaltfläche Alle neu bereitstellen oben lädt alle aktivierten Flows erneut. Verwenden Sie sie in folgenden Situationen.

  • Direkt nach dem Massenimport von Graphen von außen
  • Wenn Sie Trigger mit eigenem Scheduler (Schedule·externes MQTT-Abonnement·externes DB-Polling) erneut registrieren möchten
  • Bei Verdacht auf Cache-Konsistenzprobleme während des Betriebs

Bearbeitungsbildschirm (visuelle Canvas)​

Ziehen Sie Nodes aus der linken Palette der Canvas, und verbinden Sie den Ausgangsport eines Nodes durch Klicken & Ziehen mit dem nächsten Node.

Obere Werkzeugleiste​

SchaltflächeAktion
Name·BeschreibungFlow-Metainformationen bearbeiten
Bereitstellen/AufhebenDen aktuellen Flow sofort aktivieren/deaktivieren
ExportierenDen gesamten Graphen als JSON-Datei herunterladen
TestlaufEine beliebige JSON-Nachricht einmalig einspeisen und das Ergebnis prüfen (siehe Verwendung des Testlaufs unten)
SpeichernDen aktuellen Graphen auf dem Server speichern. Beim Speichern wird ein automatischer Snapshot angelegt, sodass später zurückgerollt werden kann

Wenn Sie versuchen, einen Graphen ohne Trigger zu speichern, wird die Warnung „Wird nur über manuellen Testlauf gestartet“ angezeigt. Sie können den Trigger absichtlich weglassen und den Flow ausschließlich für manuelle Ausführung nutzen.

Verwendung des Testlaufs​

Beim Klick auf die Schaltfläche 테스트 실행 öffnet sich ein JSON-Bearbeitungsdialog. Der Operator kann selbst eine Nachricht schreiben und einmalig veröffentlichen, um das Verhalten des Graphen zu prüfen, ohne auf ein Trigger-Ereignis zu warten.

ElementBeschreibung
EditorJSON-Editor mit Zeilennummern·Syntaxhervorhebung. Der Nachrichteninhalt kann frei geschrieben werden
ValidierungsanzeigeBei vorhandenen Pflichtfeldern type wird ✓ JSON OK (type=X) angezeigt, bei fehlenden Feldern ⚠ type 필수
VeröffentlichenÜber die Schaltfläche 발행 wird die Nachricht in den Dispatcher eingespeist. Das Ergebnis ist im Live-Debug-Panel und in der Ausführungshistorie einsehbar

Beispiel für Standardvorlage

{
"type": "POST_TELEMETRY",
"originator": { "entity_type": "Asset", "id": "MOTOR-001" },
"data": { "speed": 1500, "temp": 75.3 },
"metadata": { "ts": 1746247200000, "site_id": "SITE-01" }
}

Wenn Sie ungespeicherte Änderungen haben und den Testlauf ausführen, erscheint der Hinweis „Der Server führt die gespeicherte Version aus“. Um Änderungen zu prüfen, speichern Sie zuerst.

Kann kategorieweise auf-/zugeklappt werden; über das Suchfeld kann sofort gefiltert werden.

KategorieFarbeAnzahl Nodes
Trigger (Trigger)Grau22
Filter (Filter)Blau6
Transformation (Transform)Grün8
Aktion (Action) — Integration·Speicherung·Anlagen-Ereignis-Veröffentlichung·BefehlsaufrufOrange7
Aktion (Action) — Domain CRUDOrange34
Externe Anbindung (External)Violett9
Ablaufsteuerung (Control)Grau7
Edge (Edge)Cyan22

Mitte — Canvas​

WerkzeugTastenkürzel/BedienungAktion
ZoomenCtrl/⌘ + / Ctrl/⌘ - · MausradCanvas zoomen
100%Ctrl/⌘ 0Zoom zurücksetzen
An Ansicht anpassenCtrl/⌘ 1Automatisch anpassen, damit alle Nodes sichtbar sind
Ausgewählten Node löschenDel / BackspaceAusgewählten Node/Wire löschen
Canvas verschieben (Panning)Linksklick auf leeren Bereich, dann ziehenWenn Sie den leeren Canvas-Hintergrund (nicht auf einen Node) klicken und ziehen, bewegt sich die gesamte Canvas mit

Unten rechts auf der Canvas wird eine Minimap angezeigt; ein Klick auf die Minimap springt sofort zur entsprechenden Position.

💡 Tipp zum Panning: Ziehen auf einem Node bewegt den Node — um die Canvas zu verschieben, greifen Sie unbedingt den leeren Hintergrundbereich ohne Node/Wire. Bei großen Flows ist Panning schneller als die Minimap.

Rechts — Node-Konfiguration​

Wenn Sie einen Node auf der Canvas anklicken, wird im rechten Inspektor das Konfigurationsformular des betreffenden Nodes angezeigt. Die Eingabefelder werden je nach Node-Typ automatisch erzeugt.

EingabeartBeschreibung
Statischer WertVerwendet den direkt im Formular eingegebenen Wert unverändert
*_field dynamischer WertExtrahiert den Wert aus einem Pfad in der Nachrichten-Payload (z. B. data.tag_id, metadata.site_id). Fehlt der Wert, wird auf den statischen Wert zurückgegriffen

Script-Nodes (Filter·Transformation·Switch) können direkt im Inspektor per Code-Editor bearbeitet werden und lassen sich auch in einem separaten Dialog erweitern, um auf einem größeren Bildschirm zu schreiben.

Die Code-Editor-Schriftart wird als lesbarkeitsoptimierter Monospace-Font-Stack (Priorität: Cascadia Code · JetBrains Mono · Consolas · Menlo) angezeigt, wobei auch koreanische Kommentare stabil ausgerichtet werden.

Zähler zurücksetzen​

Oben rechts im Node-Konfigurationspanel werden zwei Reset-Schaltflächen als Icons angezeigt. Beim Überfahren mit der Maus zeigt jede Schaltfläche einen Tooltip.

Icon-SchaltflächeAktion
🩹 (Pflaster) — Fehlerzähler zurücksetzenSetzt nur den kumulierten Fehlerzähler aller Nodes in diesem Flow auf 0 zurück
🔄 (Drehpfeil) — Alle Zähler zurücksetzenSetzt Verarbeitung·Fehler·Verarbeitungszeit sowie alle Flow-bezogenen Statistiken auf 0 zurück. Verwenden Sie dies nach Abschluss der Betriebsverifizierung, um mit neuen Statistiken zu beginnen

Beide Schaltflächen wirken sofort ohne Bestätigungsdialog — nur die Statistik wird zurückgesetzt, das Node-Verhalten bzw. die Nachrichtenverarbeitung sind nicht betroffen.

Rechts — Live-Debug​

Das Live-Debug-Panel wird unter dem Inspektor angezeigt.

ElementBeschreibung
Aktualisierungsintervall2 Sekunden
Level-FarbeAm linken Rand INFO (Blau)/WARN (Gelb)/ERROR (Rot)
Angezeigte InformationenNode-Anzeigename · Verarbeitungszeit (ms) · Nachrichtenvorschau
PauseAktualisierung über Schalter oben rechts im Panel pausieren
LeerenKumulierte Debug-Einträge nur auf dem Bildschirm leeren

Oben rechts an jedem Node auf der Canvas wird eine kleine Leuchtanzeige angezeigt.

FarbeBedeutung
GrauWartend — noch keine Nachricht empfangen
GrünNachricht durchläuft gerade
RotFehler während der Verarbeitung aufgetreten

Unten rechts am Node wird die Verarbeitungszeit im Format 평균 X · 최근 Y angezeigt.


Nachrichtenstruktur​

Die im Flow fließende Nachricht besteht aus folgenden 4 Bereichen.

{
"type": "POST_TELEMETRY",
"originator": {
"entity_type": "Asset",
"id": "MOTOR-001"
},
"data": { "speed": 1500, "temp": 75.3 },
"metadata": {
"ts": 1746247200000,
"site_id": "SITE-01",
"shift": "DAY",
"tag_id": "MOTOR-001.SPEED"
}
}
BereichBedeutung
typeNachrichtenklassifizierung. Verzweigungskriterium des Filter-Nodes
originatorSubjekt-Entität der Nachricht (auf welche Anlage/Tag/Bestellung sie sich bezieht)
dataPayload-Inhalt
metadataKontext (Zeit·Standort·Schicht·Tag-ID usw.)

Nachrichtentypen​

TypAuslösender Einstiegspunkt
POST_TELEMETRY / TAG_POINTEingang eines Tag-Datenpunkts
POST_ATTRIBUTESAktualisierung der Tag-/Anlagen-Metadaten
TAG_ALARMAlarm auf Tag-Ebene
ENTITY_CREATED / UPDATED / DELETEDLebenszyklus-Ereignisse einer Entität
ASSET_DATA / ASSET_EVENT / ASSET_ALARM / ASSET_COMMAND / ASSET_AGGREGATION / ASSET_CONTEXTAnlagen-Domain-Ereignisse
ASSET_HEALTH_STATUS / ASSET_CONNECTION_STATUSPeriodische Anlagenbewertung (Health-/Verbindungsstatus)
OEE_EVENT / RAM_EVENT / EMS_EVENTISO-Analyseergebnis-Ereignisse
OPC_STATUS / EDGE_STATUSOPC/Edge-Gerätestatus
DIAGNOSTIC / DOMAIN_CHANGEDDiagnose·Domänenänderung
ALARMAlarmauslösung
WEBHOOKEmpfang von HTTP-Webhooks
KAFKA_INBOUND / MQTT_INBOUNDEmpfang externer Topics
TIMERSchedule-Auslösung

Payload-Beispiele nach Trigger​

Bei der Erstellung von Script-Nodes müssen Sie genau wissen, auf welche Felder zugegriffen werden kann. Nachfolgend finden Sie reale JSON-Nachrichtenbeispiele, die jeder Trigger erzeugt. Alle Trigger-Nachrichten enthalten gemeinsam type, originator, data, metadata.

flow_on_tag_point — Eingang eines Tag-Datenpunkts​

Wird jedes Mal ausgelöst, wenn ein Wert für ein Tag eingeht. Der häufigste Trigger.

{
"type": "POST_TELEMETRY",
"originator": { "entity_type": "Tag", "id": "MOTOR-001.SPEED" },
"data": {
"value": 1500.7,
"quality": "GOOD",
"ts": 1746247200123
},
"metadata": {
"tag_id": "MOTOR-001.SPEED",
"site_id": "SITE-01",
"area_id": "AREA-A",
"line_id": "LINE-1",
"asset_id": "MOTOR-001",
"opc_id": "OPC-LINE-1",
"java_type": "Float",
"unit": "rpm",
"shift": "DAY"
}
}
FeldBedeutungSkriptzugriff
data.valueEmpfangener Wert (numerisch/String/boolesch)msg.data.value
data.qualityOPC-Qualität (GOOD/BAD/UNCERTAIN)msg.data.quality
data.tsEmpfangszeitpunkt (epoch ms)msg.data.ts
metadata.tag_idTag-IDmsg.metadata.tag_id

flow_on_tag_alarm — Auftreten eines Tag-Alarms​

Wird ausgelöst, sobald das Tag ein Alarmband (hi/lo/...) überschreitet.

{
"type": "TAG_ALARM",
"originator": { "entity_type": "Tag", "id": "MOTOR-001.TEMP" },
"data": {
"alarm_band": "HI_HI",
"value": 95.3,
"threshold": 90.0,
"priority": "ERROR",
"band_message": "온도 위험"
},
"metadata": {
"tag_id": "MOTOR-001.TEMP",
"asset_id": "MOTOR-001",
"site_id": "SITE-01",
"ts": 1746247200123
}
}
data.alarm_band-WertBedeutung
NORMAL / HI / LO / HI_HI / LO_LO / TRIP_HI / TRIP_LONumerische Alarmstufen
BOOL_TRUE / BOOL_FALSEBoolesche Alarme

flow_on_asset_data / flow_on_asset_event — Anlagen-Ereignis​

Wird ausgelöst, wenn auf Anlagenebene aggregierte Ereignisse (CEP-Verarbeitungsergebnis·Plugin-Bewertungsergebnis usw.) auftreten.

{
"type": "ASSET_EVENT",
"originator": { "entity_type": "Asset", "id": "MOTOR-001" },
"data": {
"event_type": "STARTUP",
"details": { "rpm_target": 1500 }
},
"metadata": {
"asset_id": "MOTOR-001",
"site_id": "SITE-01",
"ts": 1746247200123
}
}

flow_on_asset_data übermittelt Zeitreihendaten auf Anlagenebene (data.values als Schlüssel-Wert-Map), flow_on_asset_aggregation übermittelt Aggregatwerte auf Minuten-/Stundenbasis.

flow_on_asset_health_status / flow_on_asset_connection_status — Periodische Bewertung​

Die Plattform bewertet im Minutentakt den Health-/Verbindungsstatus auf Anlagenebene.

{
"type": "ASSET_HEALTH_STATUS",
"originator": { "entity_type": "Asset", "id": "MOTOR-001" },
"data": {
"status": "WARN",
"info_count": 12,
"warn_count": 3,
"error_count": 0,
"prev_status": "OK"
},
"metadata": { "asset_id": "MOTOR-001", "ts": 1746247200123 }
}
data.status-WertBedeutung
OK / WARN / ERROR / UNKNOWNHealth-Stufen
CONNECTED / LATENT / ERROR / DISCONNECTED / UNKNOWNVerbindungsstufen (connection_status)

Ein oft verwendetes Muster ist, im Vergleich mit prev_status nur beim Zeitpunkt des Statuswechsels eine Folgeaktion auszulösen.

flow_on_oee_event / flow_on_ram_event / flow_on_ems_event — Plugin-Ereignisse​

Wird ausgelöst, wenn OEE/RAM/EMS-Bewertungsergebnisse auf Arbeitsauftragsebene aktualisiert werden. Absender (originator) ist die Anlage, das Berechnungsergebnis steht in data.payload.

{
"type": "OEE_EVENT",
"originator": { "entity_type": "Asset", "id": "ASSET_DJ_M_0001" },
"data": {
"event_type": "OEE_CALCULATED",
"plugin": "OEE",
"statement_type": "RESULT",
"asset_id": "ASSET_DJ_M_0001",
"timestamp": 1746247200123,
"payload": {
"oee": 0.78,
"availability": 0.95,
"performance": 0.85,
"quality": 0.97,
"good_quantity": { "quantity_string": "1560", "data_type": "integer", "unit_of_measure": "EA" },
"scrap_quantity": { "quantity_string": "42", "data_type": "integer", "unit_of_measure": "EA" },
"rework_quantity": { "quantity_string": "6", "data_type": "integer", "unit_of_measure": "EA" },
"run_time_ms": 25200000,
"order_id": "ORDER_000001"
}
}
}
  • good_quantity, scrap_quantity und rework_quantity sind Quantity-Objekte in der Einheit des Arbeitsauftrags (ISA-95 / B2MML). Der Wert ist ein Dezimal-String; um im Skript damit zu rechnen, wandeln Sie ihn um, z. B. Number(data.payload.good_quantity.quantity_string), und prüfen die Einheit in unit_of_measure. Die alten Felder good_count und bad_count gibt es nicht mehr. Feldregeln: Order-Dienst — Menge.
  • scrap_quantity ist nur Ausschuss, Nacharbeit ist rework_quantity. Wird die Summe der Schlechtteile benötigt, addieren Sie beide (Gut + Ausschuss + Nacharbeit = Produktion).
  • Ein nicht berechnetes Verhältnis («nicht angewendet») und eine fehlende Menge sind null, nicht 0.

flow_on_opc_status / flow_on_edge_status — OPC/Edge-Status​

{
"type": "OPC_STATUS",
"originator": { "entity_type": "OPC", "id": "OPC-LINE-1" },
"data": {
"connection_status": "CONNECTED",
"scan_status": "START",
"prev_status": "DISCONNECTED"
},
"metadata": { "opc_id": "OPC-LINE-1", "edge_id": "EDGE-A", "ts": 1746247200123 }
}

flow_on_diagnostic — Systemdiagnosenachricht​

Wird ausgelöst, wenn eine Diagnosemeldung von einem Servermodul eingeht.

{
"type": "DIAGNOSTIC",
"originator": { "entity_type": "Module", "id": "cep-engine" },
"data": {
"level": "WARN",
"code": "PATTERN_LAG",
"summary": "EQL 패턴 평가 지연 1.2s",
"module": "cep-engine"
},
"metadata": { "ts": 1746247200123 }
}
data.levelBedeutung
INFO / WARN / ERRORDiagnoseschweregrad

flow_on_domain_changed — Domänenänderungsereignis​

Wird ausgelöst, wenn Domänenentitäten wie Anlage·Tag·Standort·Arbeitsauftrag per CRUD verändert werden.

{
"type": "DOMAIN_CHANGED",
"originator": { "entity_type": "Asset", "id": "MOTOR-001" },
"data": {
"action": "UPDATED",
"before": { "asset_name": "Motor1" },
"after": { "asset_name": "Motor 01 - Renamed" },
"changed_by": "admin"
},
"metadata": { "ts": 1746247200123 }
}

flow_on_entity_event — Entitäts-Lebenszyklus​

Ausgelöst als drei zusammengefasste Typen: ENTITY_CREATED / ENTITY_UPDATED / ENTITY_DELETED. Ein einziger Node empfängt alle drei Lebenszyklen.

{
"type": "ENTITY_CREATED",
"originator": { "entity_type": "Customer", "id": "CUST-9001" },
"data": { "customer_name": "신규 고객", "external_id": "ERP-CUST-9001" },
"metadata": { "ts": 1746247200123 }
}

flow_on_webhook — Externer HTTP-Push​

Eine von einem externen System an POST /webhook/flow/{flow_id} gesendete Payload wird unverändert in eine Nachricht umgewandelt. Authentifizierung über {flow_id} im URL-Pfad und Header X-API-Key.

Der alte Pfad /flow/webhook/{flow_id} liefert 410 Gone zurück

Dieser Pfad wurde deaktiviert, da er ohne Authentifizierung beliebige Flows über flow_id auslösen konnte (FlowController liefert 410). Der neue Einstiegspunkt /webhook/flow/{flow_id} wird von WebhookController per API-Key·HMAC validiert. Der Pfad ist vertauscht und dadurch leicht zu übersehen — es ist nicht flow/webhook, sondern webhook/flow.

{
"type": "WEBHOOK",
"originator": { "entity_type": "External", "id": "ERP" },
"data": {
"order_no": "PO-20260512-001",
"customer": "ACME",
"quantity": 1000
},
"metadata": {
"http_method": "POST",
"remote_addr": "10.20.0.55",
"request_id": "req-7c0a...",
"ts": 1746247200123
}
}

Der komplette von einem externen System gesendete JSON-Body wird unverändert in data eingesetzt. Die HTTP-Header werden nur teilweise (remote_addr/method/request_id) in metadata angezeigt.

flow_on_mqtt_subscribe — Abonnement eines MQTT-Topics​

{
"type": "MQTT_INBOUND",
"originator": { "entity_type": "Topic", "id": "factory/line1/events" },
"data": { "event": "STARTUP", "rpm": 1500 },
"metadata": {
"topic": "factory/line1/events",
"qos": 1,
"broker": "tcp://mqtt.example.com:1883",
"ts": 1746247200123
}
}

flow_jdbc_poll — Periodisches Polling einer externen DB​

Führt die konfigurierte SELECT-Query periodisch aus und löst für jede Zeile eine Nachricht aus.

{
"type": "KAFKA_INBOUND",
"originator": { "entity_type": "DB", "id": "mes_db" },
"data": {
"PO_NO": "PO-20260512-001",
"CUSTOMER": "ACME",
"QTY": 1000,
"DUE_DATE": "2026-05-20"
},
"metadata": {
"datasource": "mes_db",
"query": "SELECT * FROM po WHERE status='NEW'",
"row_index": 0,
"ts": 1746247200123
}
}

Bei 100 Zeilen werden 100 Nachrichten der Reihe nach ausgelöst. Um zu verhindern, dass dieselbe Zeile wiederholt verarbeitet wird, aktualisieren Sie ein Verarbeitungsflag innerhalb der SELECT-Query oder fügen Sie eine Vergleichsbedingung für die Spalte processed_at hinzu.

flow_schedule — Zeitbasierte Auslösung​

Wird per Cron-Ausdruck oder festem Intervall ausgelöst. Die Payload ist leer, nur metadata.ts wird befüllt.

{
"type": "TIMER",
"originator": { "entity_type": "Schedule", "id": "daily-report" },
"data": {},
"metadata": {
"cron": "0 0 8 * * ?",
"fired_at": 1746247200000,
"ts": 1746247200000
}
}

Hinweise bei der Payload-Transformation​

  • originator.id ist die Domänen-ID — wenn sie mit dem Node flow_change_originator geändert wird, arbeiten nachfolgende Aktions-Nodes wie flow_save_attributes·flow_publish_asset_* ab dann mit dem neuen Originator.
  • Beim Ersetzen von data/metadata per Skript wird eine direkte Zuweisung statt einer flachen Kopie (Object.assign) empfohlen — Änderungen am Original können andere Flows beeinflussen, die denselben Trigger abonnieren.
  • Alle epoch-Zeitfelder sind in Millisekunden (ms) angegeben. Falls Sekunden benötigt werden: Math.floor(msg.metadata.ts / 1000).

Node-Katalog​

Detaillierte Node-IDs und Optionen finden Sie im Inspektor des Bearbeitungsbildschirms.

Trigger (22 Typen)​

Der Startpunkt jedes Flows ist ein Trigger-Node. Es gibt keine separaten Einstiegs-/Endpunktknoten.

Automatischer Domain-Empfang — interne Systemereignisse werden automatisch dispatcht.

KategorieTrigger-Node
Tagflow_on_tag_point (Telemetrie), flow_on_tag_alarm
Anlageflow_on_asset_data, flow_on_asset_event, flow_on_asset_alarm, flow_on_asset_command, flow_on_asset_aggregation, flow_on_asset_context, flow_on_asset_health_status, flow_on_asset_connection_status
Pluginflow_on_oee_event, flow_on_ram_event, flow_on_ems_event
OPC/Edgeflow_on_opc_status, flow_on_edge_status
Diagnose·Domainflow_on_diagnostic, flow_on_domain_changed
Entitätflow_on_entity_event
Es gibt keinen Node namens flow_on_alarm

Alarm-Trigger sind je nach Ziel zweigeteilt — Tag-Alarme sind flow_on_tag_alarm, Anlagen-Alarme sind flow_on_asset_alarm. Ein älteres Beispiel verwendete flow_on_alarm, das jedoch nicht in der Palette vorhanden ist — folgen Sie diesem Namen nicht, sonst finden Sie den Node nicht.

Alle Trigger-Nodes können über die Option *_pattern (Glob: *, ?) eine Vorabfilterung pro Nachricht vornehmen. Nicht übereinstimmende Nachrichten werden nicht an Folgenodes weitergegeben und erhöhen auch den Ausführungszähler nicht (Behandlung als SKIPPED). Es wird empfohlen, Filterung bereits auf Trigger-Ebene vorzunehmen, um die Betriebslast zu minimieren.

Externer Eingang

NodeAktion
flow_on_webhookEmpfang von per HTTP von externen Systemen gepushten Payloads
flow_on_mqtt_subscribeAbonnement eines Topics eines externen MQTT-Brokers
flow_jdbc_pollPeriodisches Lesen des SELECT-Ergebnisses einer externen Datenbank, Auslösung pro Zeile

Zeitbasiert

NodeAktion
flow_scheduleCron-/Intervall-Schedule — löst Nachricht TIMER aus

Filter (6 Typen)​

NodeBeschreibung
flow_msg_type_filterWenn type in der angegebenen Liste enthalten ist, TRUE
flow_originator_type_filterWenn originator.entity_type in der angegebenen Liste enthalten ist, TRUE
flow_script_filterBoolesche Auswertung per Skript
flow_check_existence_fieldExistenzprüfung bestimmter Felder data/metadata
flow_switchMehrfache Case-Verzweigung (unterschiedliche Relation je Case)
flow_check_relationVerzweigung nach der Relation der vorherigen Stufe

Transformation (8 Typen)​

NodeAnzeigenameBeschreibung
flow_script_transformSkripttransformationdata/metadata per Skript transformieren
flow_change_originatorAbsender ändernoriginator in eine andere Entität ändern
flow_rename_keysSchlüsselnamen ändernFeldnamen von data pauschal umbenennen
flow_templateVorlage${path} Substitutionstext erzeugen
flow_splitAufteilenFalls data ein Array ist, in eine Nachricht pro Element aufteilen
flow_mergeZusammenführenMehrere Nachrichten über ein Zeitfenster zusammenführen — das Gegenteil von flow_split
flow_flattenAbflachenKindschlüssel eines verschachtelten Objekts auf die oberste Ebene heben (data.data_map.x → data.x)
flow_to_emailE-Mail-UmwandlungNachricht in E-Mail-Format umwandeln

flow_flatten wird verwendet, wenn Sie Nachrichten, bei denen der Wert wie bei einem Tag-Datenpunkt zusätzlich in data_map verschachtelt ist, im nachfolgenden Node direkt über ${data.x} referenzieren möchten.

Aktion — Integration/Speicherung (2 Typen)​

NodeBeschreibung
flow_save_tag_pointSpeicherung eines Tag-Datenpunkts (identisch mit dem normalen Ingest-Pfad)
flow_save_attributesTeilweise Aktualisierung von Tag-/Anlagen-Metadaten

Wenn Sie flow_dds_publish (freies Publizieren in den internen Nachrichtenkanal) suchen, finden Sie es nicht hier, sondern in der Palettengruppe Externe Anbindung.

Aktion — Anlagen-Ereignis-Veröffentlichung (4 Typen)​

Veröffentlicht Anlagen-Ereignisse über denselben Verarbeitungspfad wie CEP (EQL) (persistente Speicherung + Cache + Timeline + Plugin + konsistente Verarbeitung im Nachrichtenkanal).

NodeKanal
flow_publish_asset_eventAnlagen-Ereignis
flow_publish_asset_contextAnlagenkontext
flow_publish_asset_aggregationAnlagenaggregation
flow_publish_asset_commandAnlagenbefehl

flow_asset_command_invoke — Ausführung statt Veröffentlichung​

NodeAnzeigenameWas es tut
flow_asset_command_invokeAnlagenbefehl-AufrufFührt einen an der Anlage definierten Befehl synchron aus und wartet auf das Ergebnis
Leicht zu verwechseln mit flow_publish_asset_command
  • flow_publish_asset_command — veröffentlicht ein Anlagenbefehls-Ereignis im Kanal. Damit ist es abgeschlossen.
  • flow_asset_command_invoke — führt tatsächlich einen an der Anlage definierten Befehl aus und wartet auf das Ergebnis.

Wenn Sie einen Befehl tatsächlich ausführen wollten, aber den Veröffentlichungsnode verwenden, scheint nichts zu passieren.

Aktion — Domain CRUD (34 Typen)​

Alle Domänen-Operationen werden an denselben Domänenservice delegiert, wodurch Audit·Konsistenz gewahrt bleiben. Mit der dynamischen Option *_field können Werte aus der Nachrichten-Payload extrahiert werden.

DomäneCreateUpdateDelete
Anlage (Asset)flow_create_assetflow_update_assetflow_delete_asset
Tag (Tag)flow_create_tagflow_update_tagflow_delete_tag
Standort/Bereich/Linieflow_create_siteflow_update_siteflow_delete_site
Arbeitsauftrag (WorkOrder)flow_create_work_orderflow_update_work_orderflow_delete_work_order
Alarmeinstellung (EQL)flow_create_alarm_configflow_update_alarm_configflow_delete_alarm_config
Kunde (Customer)flow_create_customerflow_update_customerflow_delete_customer
Produkt (Product)flow_create_productflow_update_productflow_delete_product
Mitarbeiter (Employee)flow_create_employeeflow_update_employeeflow_delete_employee
Kalender (Schicht)flow_create_calendarflow_update_calendarflow_delete_calendar

Teilweise Aktualisierung des Tag-Alarmbands (2 Typen)​

NodeBeschreibung
flow_update_tag_alarm_band_numericAktualisiert nur die eingegebenen Felder des numerischen Alarmbands (hi/lo/hi_hi/lo_lo/trip_hi/trip_lo/band_message/use_alarm)
flow_update_tag_alarm_band_booleanAktualisiert nur die eingegebenen Felder des booleschen Alarmbands (bool_true/bool_false/Priorität/Nachricht/use_alarm)

Zustandsübergänge des Arbeitsauftrags (WorkOrder) (5 Typen)​

Da statt direkter Aktualisierung numerischer Spalten die Zustandsübergangsmethoden des Domänenservices aufgerufen werden, bleibt die OEE/RAM/EMS-Sichtbarkeit erhalten.

NodeÜbergang
flow_start_work_orderWAIT → START
flow_pause_work_orderSTART → PAUSED
flow_resume_work_orderPAUSED → START
flow_end_work_orderSTART oder PAUSED → END
flow_abort_work_orderSTART oder PAUSED → ABORTED (Optionen abort_code, notes)

Automatische NOT-NULL-Ergänzung — Create-Nodes befüllen NOT-NULL-Spalten automatisch mit Default-Werten. Beispiel: Arbeitsauftrag status="WAIT" / master_id als MES-Master-ID (falls nicht vorhanden, automatisches Backfill), Kundenmanagerinformationen "admin"/"admin@example.com", Mitarbeiter org_id mit Fallback auf site_id, insert_user_id="flow" für alle Zeilen. Bei FK-Spalten (z. B. customer_id/product_id) wird ein leerer String in NULL umgewandelt.

Update-Node — Teilweise Aktualisierung — Die Update-Nodes für Customer/Product/Employee/Calendar und das Alarmband rufen zunächst den bestehenden Datensatz ab und speichern dann nur die eingegebenen Felder als Merge. Leere Strings·Null-Werte werden ignoriert und der bestehende Wert bleibt erhalten. Für vollständiges Überschreiben verwenden Sie die Kombination Delete + Create.

Der Node zur direkten Alarmauslösung wurde bewusst ausgeschlossen. Alarme sollten nur über den flow_create_alarm_config-Pfad entstehen, damit die Konsistenz der Alarmhistorie gewahrt bleibt.

Edge (Edge, 22 Typen)​

Automatisiert die Registrierung von OPC-Servern·Tag-CRUD·Abfrage von Tag-Werten (Lesen/Schreiben)·Steuerung von Docker-Apps durch Aufruf der REST-API des Edge-Geräts (OPC Agent). Alle Nodes teilen semantisch dieselbe Aktion, wobei sich nur die zugrunde liegende HTTP-Methode (GET/POST/PUT/DELETE) unterscheidet.

GruppeNode
OPC-Server-Verwaltungflow_edge_opc_create, flow_edge_opc_update, flow_edge_opc_delete, flow_edge_opc_start, flow_edge_opc_stop, flow_edge_opc_list
Tag-Verwaltungflow_edge_tag_create, flow_edge_tag_update, flow_edge_tag_delete, flow_edge_tag_read, flow_edge_tag_write, flow_edge_tag_list
Abfrageflow_edge_monitoring, flow_edge_info, flow_edge_transfer
Docker-App-Steuerungflow_edge_app_list, flow_edge_app_inspect, flow_edge_app_start, flow_edge_app_stop, flow_edge_app_restart, flow_edge_app_logs, flow_edge_app_stats

Abfrage (3 Typen)​

NodeAnzeigenameWas es tut
flow_edge_monitoringMonitoringAbfrage der Edge-Monitoring-Kennzahlen
flow_edge_infoEdge-InfoAbfrage von Edge-ID · Version · Uptime
flow_edge_transferÜbertragungs-HealthMQTT/Sparkplug-Übertragungsstatus
NodeAnzeigenameWas es tut
flow_edge_opc_listOPC-ListeAbfrage der OPC-Serverliste des Edge
flow_edge_tag_listTag-ListeAbfrage der OPC-Tag-Liste

Docker-App-Steuerung (7 Typen)​

Automatisiert per Flow, was manuell im Docker-Panel des Edge-Detailbildschirms erledigt wird.

NodeAnzeigenameWas es tut
flow_edge_app_listApp-ListeListe der Docker-Container des Edge
flow_edge_app_inspectApp-DetailsContainer-Details (inspect)
flow_edge_app_startApp startenContainer starten
flow_edge_app_stopApp stoppenContainer stoppen
flow_edge_app_restartApp neu startenContainer neu starten
flow_edge_app_logsApp-LogContainer-Log (line=N)
flow_edge_app_statsApp-StatistikenContainer CPU / Speicher / I/O
Die App-Steuerungsnodes greifen tatsächlich in die Vor-Ort-Geräte ein

app_stop · app_restart stoppen und starten den tatsächlich auf dem Vor-Ort-Edge laufenden Container. Wenn Sie diese an einen Trigger anbinden, um sie automatisch auszuführen, setzen Sie enge Bedingungen — wenn Sie app_restart an einen flappenden Alarm anschließen, startet der Container wiederholt neu.

Gemeinsame Konfiguration

OptionBeschreibung
urlEdge-REST-Endpunkt. Unterstützt ${data.x}/${metadata.y}-Vorlagensubstitution
methodHTTP-Methode (bei fehlender Angabe Node-spezifischer Standardwert — z. B. create=POST, update=PUT, delete=DELETE, read/monitoring=GET)
headersJSON-Header (z. B. {"Authorization":"Bearer ${TOKEN}"})
body_templateRequest-Body (bei fehlender Angabe wird data unverändert gesendet, GET/DELETE senden keinen Body)
timeout_msTimeout (Standard 5000)

Antwort·Verzweigung

  • data.response_status — HTTP-Statuscode
  • data.response — Response-Body (String)
  • data.error — Fehlermeldung (bei Fehlschlag)
  • SUCCESS (200–399) / FAILURE (sonst oder Ausnahme)

Externe Anbindung (9 Typen)​

Alle externen Nodes unterstützen die dynamische Option *_field.

NodeDynamische Option
flow_dds_publishFreies Publizieren in den internen Nachrichtenkanal (kein externer Aufruf, aber in dieser Gruppe enthalten)
flow_http_requesturl_field / method_field / body_field
flow_kafka_publishtopic_field / key_field
flow_mqtt_publishtopic_field
flow_webhook_callbackurl_field
flow_send_emailto_field / cc_field / subject_field / body_field
flow_send_smsto_field / text_field
flow_send_pushtitle_field / body_field
flow_jdbc_querySQL statisch (SELECT/INSERT/UPDATE/DELETE)

Ablaufsteuerung (7 Typen)​

NodeBeschreibung
flow_logDebug-Log (level / prefix)
flow_noopDurchleiten
flow_delayNach delay_ms Weiterleitung an den nächsten Node
flow_throttleBegrenzung von max_msgs / window_ms (bei Überschreitung Relation THROTTLED)
flow_debounceNach Stabilisierung über window_ms nur die letzte Nachricht auslösen
flow_mergeEingaben über window_ms kumulieren und einmalig als data.merged-Array emittieren
flow_subflowtarget_flow_id — Aufruf eines anderen Flows
flow_retrymax_attempts (Standard 3) / backoff_ms (Standard 1000) / backoff_multiplier (Standard 2.0). Nach Backoff-Wartezeit Weiterleitung der Nachricht über SUCCESS-Zweig, bei Erreichen der Maximalversuche Zweig EXHAUSTED. Automatische Aktualisierung von metadata.retry_count / metadata.retry_exhausted

Empfohlenes Retry-Verdrahtungsmuster​

[risky_node] ─[FAILURE]─▶ [flow_retry] ─[SUCCESS]─▶ (다시 risky_node 로 루프 연결)
└[EXHAUSTED]─▶ [에러 핸들러 / 알림]

Detaillierte Node-Optionsreferenz​

Erläutert die Optionen komplexer Nodes nicht nur zeilenweise, sondern detailliert bis hin zu Standardwerten·Beispielen·Fehlerbehandlung pro Option.

flow_script_filter — Skriptfilter​

OptionTypStandardwertBeschreibung
scripttext(erforderlich)Auswertungsausdruck — gibt boolean zurück. true → Zweig TRUE / false → Zweig FALSE
script_typeenumjavascriptjavascript / eql
on_errorenumFALSEBei Skriptausnahme — Zweig TRUE / FALSE / FAILURE

Skriptkontext​

VariableBedeutung
msg.typeNachrichtentyp (POST_TELEMETRY usw.)
msg.dataPayload (änderbar, aber im Filter ohne Bedeutung)
msg.metadataKontext
msg.originatorOriginator-Objekt

Beispiel​

// 온도가 임계 초과 + 야간 시프트만
msg.data.value > 80 && msg.metadata.shift === 'NIGHT'
// 사이트별 임계 분기
var th = {'SITE-A': 80, 'SITE-B': 90, 'SITE-C': 75};
msg.data.value > (th[msg.metadata.site_id] || 100);

flow_script_transform — Skripttransformation​

OptionTypStandardwertBeschreibung
scripttext(erforderlich)Transformationsausdruck — ändert das msg-Objekt oder gibt ein neues Objekt zurück
script_typeenumjavascriptjavascript / eql
modeenummutatemutate (in-place) / return (Rückgabewert verwenden)

Beispiel​

// data 에 계산 필드 추가
msg.data.fahrenheit = msg.data.value * 9/5 + 32;
msg.metadata.processed_at = Date.now();
// 페이로드 통째로 교체 (mode=return)
return {
type: 'WEBHOOK',
originator: msg.originator,
data: { temp: msg.data.value, level: msg.data.value > 80 ? 'HIGH' : 'OK' },
metadata: msg.metadata
};

Im Modus mutate wird eine return-Anweisung ignoriert, selbst wenn vorhanden. Um durch ein neues Objekt zu ersetzen, muss mode=return eingestellt werden.

flow_switch — Mehrfachverzweigung​

OptionTypStandardwertBeschreibung
casesarray(erforderlich)Array [{expression, relation}] — Auswertung von oben nach unten, erste Übereinstimmung wird übernommen
default_relationstringDEFAULTFalls kein Case übereinstimmt
script_typeenumjavascript—

Beispiel​

// cases 설정
[
{ "expression": "msg.data.value > 90", "relation": "CRITICAL" },
{ "expression": "msg.data.value > 80", "relation": "WARN" },
{ "expression": "msg.data.value > 70", "relation": "INFO" }
]
// default_relation: "NORMAL"

Im nachfolgenden Node ist mit 4 Verzweigungslabels (CRITICAL/WARN/INFO/NORMAL) jeweils eine unterschiedliche Verarbeitung möglich.

flow_retry — Automatischer Retry​

Automatische Wiederherstellung von vorübergehenden Fehlern eines externen IO-Nodes.

OptionTypStandardwertBeschreibung
max_attemptsint3Maximale Versuchsanzahl (bei Überschreitung EXHAUSTED)
backoff_mslong1000Erste Wartezeit (ms)
backoff_multiplierdouble2.0Exponentieller Backoff-Multiplikator — 1. Versuch 1 s → 2. Versuch 2 s → 3. Versuch 4 s
max_backoff_mslong30000Obergrenze einer einzelnen Wartezeit
jitter_pctint0Zufälliges Schwanken von ±N% beim Backoff (zur Vermeidung von Thundering Herd)

Automatische Ergänzung von metadata​

FeldBedeutung
metadata.retry_countBisherige Anzahl der Versuche
metadata.retry_exhaustedBei true wird der EXHAUSTED-Zweig betreten
metadata.retry_last_errorUrsache des letzten Fehlschlags

Wenn die Summe des Backoffs 60 Sekunden übersteigt, kann die Verarbeitungswarteschlange des Triggers blockiert werden. Bei durchgängig langsamer Antwort des externen Systems begrenzen Sie zuerst die Eingangsrate mit flow_throttle.

flow_on_webhook — HTTP-Trigger​

OptionTypStandardwertBeschreibung
auth_requiredbooleantruePflichtangabe des X-API-Key-Headers — wenn deaktiviert, kann jeder den Trigger aufrufen
allowed_originscsv*Whitelist der CORS-Origins
max_body_kbint256Obergrenze der Body-Größe (bei Überschreitung Antwort 413)
payload_patternglob*Glob zur Vorabfilterung von Nachrichten

Aufrufmethode​

curl -X POST \
https://platform.example.com/webhook/flow/{flow_id} \
-H "X-API-Key: {edge_or_token_key}" \
-H "Content-Type: application/json" \
-d '{"order_no":"PO-001","customer":"ACME","quantity":1000}'
  • {flow_id} im Pfad kann im Listenbildschirm kopiert werden
  • X-API-Key ist ein im Bildschirm API Key des Edge oder API-Authentifizierungstoken ausgestelltes Token
  • Antwort: 200 OK (in Nachrichtenwarteschlange eingereiht) / 401 (Authentifizierung fehlgeschlagen) / 404 (Flow nicht vorhanden oder nicht bereitgestellt) / 413 (Body überschritten)

flow_http_request — Externer HTTP-Aufruf​

OptionTypStandardwertBeschreibung
urlstring(erforderlich)Aufzurufende URL. Unterstützt ${data.x}-Vorlagensubstitution
url_fieldstring—Bei dynamischer Abrufung der URL aus der Payload — z. B. data.endpoint
methodenumGETGET / POST / PUT / DELETE / PATCH
method_fieldstring—Methode dynamisch aus der Payload
headersjson{}Form von {"Authorization": "Bearer ${TOKEN}"}
bodytext—Statischer Body (unterstützt Vorlagensubstitution)
body_fieldstring—Bei Abruf des Bodys aus der Payload — meist data
timeout_msint5000Obergrenze der Antwortwartezeit
follow_redirectbooleantrueAutomatisches Folgen von 3xx-Redirects
verify_sslbooleantrueTLS-Zertifikatsprüfung (nur zu Testzwecken deaktivieren)

Ergänzung der Antwort-Payload​

FeldBedeutung
data.response_statusHTTP-Statuscode (200 / 404 / 500 ...)
data.response_bodyResponse-Body (bei JSON automatisch parsen)
data.response_headersResponse-Header-Objekt

Verzweigung​

  • SUCCESS — 2xx/3xx
  • FAILURE — 4xx/5xx oder Ausnahme/Timeout

flow_send_email — E-Mail senden​

OptionTypStandardwertBeschreibung
tostring—Statischer Empfänger (durch Komma getrennt)
to_fieldstring—Empfänger aus Payload extrahieren — z. B. data.recipient
cc / cc_fieldstring—Cc
bcc / bcc_fieldstring—Bcc
subject / subject_fieldstring(mind. 1 erforderlich)Betreff — mit Vorlagensubstitution
body / body_fieldtext(mind. 1 erforderlich)Inhalt (HTML zulässig)
is_htmlbooleantrueBei reiner Text-E-Mail deaktivieren
attachmentsjson[][{"url":"...","filename":"..."}]

Die SMTP-Einstellung wird vom Operator vorab in System → Einstellungen unter Mail-Einstellungen registriert. Vor der Registrierung fallen alle E-Mail-Nodes in den FAILURE-Zweig.

flow_jdbc_poll — Polling einer externen DB​

OptionTypStandardwertBeschreibung
datasource_idstring(erforderlich)In System → Einstellungen registrierter externer DB-Bezeichner
querysql(erforderlich)SELECT-Query — liefert maximal 1.000 Zeilen pro Ausführung
poll_interval_msint60000Polling-Intervall (Standard 1 Minute)
marker_columnstring—Spalte „letzter Verarbeitungszeitpunkt“ — SELECT nur der Zeilen nach dem Marker
marker_initialstring1970-01-01 00:00:00Startwert des Markers beim ersten Polling
row_limitint1000Maximale Zeilen pro Polling (auch bei Überschreitung sicher)
on_error_continuebooleantrueBei DB-Fehler nur Diagnose protokollieren und mit dem nächsten Polling fortfahren

Beispiel für die Verwendung von marker_column​

SELECT po_no, customer, qty, created_at
FROM po
WHERE created_at > :marker
ORDER BY created_at

→ In :marker wird automatisch der beim letzten Polling erhaltene Maximalwert created_at eingesetzt.

flow_kafka_publish / flow_mqtt_publish — Externe Veröffentlichung​

OptionTypStandardwertBeschreibung
brokerstring(erforderlich)kafka:9092 oder tcp://mqtt:1883
topicstring—Statisches Topic — Substitution mit ${data.x} möglich
topic_fieldstring—Topic aus Payload extrahieren (z. B. data.target_topic)
key / key_fieldstring—(nur Kafka) Nachrichtenschlüssel
body / body_fieldjson/text(mind. 1 erforderlich)Veröffentlichter Inhalt — bei fehlender Angabe wird data unverändert verwendet
qosint1(nur MQTT) 0/1/2
retainbooleanfalse(nur MQTT) Retained-Flag

flow_publish_asset_* — Anlagen-Ereignis-Veröffentlichung​

Anlagen-Ereignisse (Ereignis/Kontext/Aggregation/Befehl) werden über einen integrierten Kanal veröffentlicht, der von CEP/Plugin/Timeline gleichzeitig erkannt wird. Gemeinsame Optionen der 4 Nodes:

OptionTypStandardwertBeschreibung
asset_idstring—Statische Anlagen-ID
asset_id_fieldstring—Anlagen-ID aus Payload extrahieren (meist metadata.asset_id)
event_typestring—Klassifizierung des Anlagen-Ereignisses (z. B. STARTUP, SHUTDOWN, MAINTENANCE)
event_type_fieldstring—Klassifizierung aus Payload extrahieren
payloadjson${data}Zu veröffentlichender Inhalt — bei fehlender Angabe wird data unverändert verwendet

Bei flow_publish_asset_command wird die Nachricht sofort an das Befehlsempfangs-Topic der Anlage (asset_id/cmd/{event_type}) übermittelt und erreicht den Edge.

flow_create_* / flow_update_* — Domain CRUD​

Alle Create/Update-Nodes teilen folgendes Optionsmuster.

OptionTypBeschreibung
{컬럼명}stringStatischer Wert (falls nicht eingegeben, NULL/Default)
{컬럼명}_fieldstringWert aus Payload extrahieren (data.foo / metadata.bar)
id_strategyenumauto (systemseitig vergeben) / field (aus {도메인}_id_field extrahiert)
on_duplicateenumerror (Standard) / skip / update — nur Create-Node

Automatische NOT-NULL-Ergänzung​

Create-Nodes befüllen NOT-NULL-Spalten automatisch mit Default-Werten.

DomäneAutomatisch befüllte Spalten
Arbeitsauftragstatus="WAIT" / master_id (falls nicht vorhanden, automatisches Backfill) / insert_user_id="flow"
KundeManagerinformationen "admin" / "admin@example.com" (falls nicht registriert)
Mitarbeiterorg_id=site_id (Fallback)
Gemeinsaminsert_date=now() / insert_user_id="flow"

Behandlung leerer Strings bei FK​

Wenn in eine FK-Spalte (z. B. customer_id/product_id) ein leerer String "" eingeht, wird dieser automatisch in NULL umgewandelt. In JS ist msg.data.customer_id = '' sicherer als delete msg.data.customer_id.

flow_edge_* — Edge-REST-Aufruf​

Die 22 Nodes, die REST-Endpunkte des Edge-Geräts aufrufen, teilen gemeinsame Optionen.

OptionTypStandardwertBeschreibung
edge_idstring—Statische Edge-ID
edge_id_fieldstring—Edge-ID aus Payload extrahieren
pathstring(Node-spezifischer Standard)Edge-REST-Pfad (z. B. /api/v1/opc, /api/v1/app/grafana/start)
body_templatetext—Request-Body — bei fehlender Angabe wird data unverändert gesendet
timeout_msint5000—

Automatische Authentifizierung​

Beim Aufruf schlägt der Edge-Node automatisch den api_key des betreffenden Edge in der Master-Tabelle mm_edge nach und fügt ihn als X-API-Key-Header hinzu. Der Operator muss keine separate Konfiguration vornehmen.

Antwort-Payload​

FeldBedeutung
data.edge_response_statusEdge-Antwortcode
data.edge_responseResponse-Body
data.edge_idZiel-Edge-ID (zur Bestätigung)

Die Verzweigung ist identisch mit flow_http_request (SUCCESS / FAILURE).


Script-Node-Erstellung​

Die Nodes flow_script_filter / flow_script_transform / flow_switch unterstützen zwei Arten von Ausdrücken.

JavaScript (Standard empfohlen)​

Standard-ECMAScript-Syntax. Unterstützt mehrzeilig·var/let/const·Funktionen·Objektliteralen alle gleichermaßen.

Bindungen

VariableBeschreibung
msgGesamte Nachricht. Direkter Zugriff auf msg.data.x, msg.metadata.topic, msg.type, msg.originator.id
dataKurzalias für msg.data
metadataKurzalias für msg.metadata

Filter-Beispiel

data.temp > 80

Transformationsbeispiel

data.temp_f = data.temp * 1.8 + 32;
data.alert = data.temp > 80 ? 'HIGH' : 'OK';
msg

Switch-Beispiel (Boolean je Case)

data.t > 100 // case "Critical"

Häufig verwendetes Transformationsmuster

// 1) 단위 변환 (섭씨 → 화씨) + 라벨링
data.temp_f = data.temp * 1.8 + 32;
data.alert = data.temp > 80 ? 'HIGH' : 'OK';
msg

// 2) 메타데이터 보강 — 시간대·시프트 자동 부여
const h = new Date(metadata.ts).getHours();
metadata.shift = (h >= 6 && h < 18) ? 'DAY' : 'NIGHT';
msg

// 3) 외부 페이로드를 도메인 모델로 매핑 (MES PO → WorkOrder)
const po = data;
data = {
master_id: 'WO-MES-' + po.po_no,
asset_id: po.line_id || 'UNASSIGNED',
title: po.product_name + ' (' + po.qty + ')',
due_date: po.delivery_date,
qty: po.qty
};
msg

// 4) 실패 분기로 명시적 라우팅 (필수 필드 누락 시)
if (!data.tag_id || data.value == null) throw new Error('필수 필드 누락');
msg

// 5) 배열 분할 후 데이터 정제 — split 노드 후에 사용
data.value = parseFloat(data.raw);
data.threshold = data.value > 100;
msg

Häufig verwendetes Filtermuster

// 우선순위 화이트리스트
['ERROR', 'CRITICAL'].includes(data.priority)

// 시간대 기반 필터 (주간만 허용)
new Date(metadata.ts).getHours() >= 8 && new Date(metadata.ts).getHours() < 20

// 자산 ID 패턴 매칭
/^MOTOR-.*$/.test(originator.id)

// 임계값 + 안정성 (값이 5번 이상 누적된 경우)
data.value > data.threshold && data.consecutive_count >= 5

Benutzerskripte werden in einer sicheren Sandbox ausgeführt; Datei-, Netzwerk-, Thread- und beliebiger Klassenzugriff sind vollständig gesperrt. Wenn externe Systemaufrufe erforderlich sind, verdrahten Sie separat einen externen Anbindungs-Node wie flow_http_request.

EQL-Ausdruck​

Kompatibilitätsmodus für bestehende EQL-Nutzer. Unterstützt nur einen einzelnen Ausdruck (keine mehrzeilige Ausführung, keine Trennung durch Semikolon), es können nur Muster mit Seiteneffekten verwendet werden.

#msg.getData().getInt('temp') > 80

Bei Bedarf mehrerer Aktionen verwenden Sie JavaScript.

JavaScript-Ausführungsumgebungsspezifikation​

Skripte werden in einer isolierten Sandbox ausgeführt. Sie müssen genau wissen, welche Funktionen möglich/nicht möglich sind, um stabile Skripte zu schreiben.

Verfügbar (✅)​

FunktionAnmerkung
Standard-ECMAScriptvar/let/const·Funktionen·Klassen·Destrukturierung·Spread·?.·?? usw.
Objektliteral{ key: value, ... }
Array-Methodenmap / filter / reduce / forEach / find / some / every / flat / slice
String-Methodensplit / replace / includes / match / padStart / repeat
Mathematische FunktionenVollständiges Math.*
JSONJSON.parse / JSON.stringify (kein erneutes stringify nötig, wenn data bereits ein Objekt ist)
Datenew Date() / Date.now() / getHours() / toISOString() usw.
Reguläre AusdrückeLiteral /pattern/ + Konstruktor RegExp
Error throwthrow new Error('...') — automatische Verzweigung in den FAILURE-Zweig
try/catch/finallyAusnahmebehandlung

Nicht verfügbar (❌)​

FunktionGrund / Alternative
Netzwerkaufruf (fetch / XMLHttpRequest)Sandbox-gesperrt — separaten flow_http_request-Node verdrahten
Dateisystem (require('fs'))Sandbox-gesperrt
Threads (setTimeout / setInterval / Worker)Nur synchrone Ausführung erlaubt — bei Verzögerungsbedarf Node flow_delay
require / importLaden externer Module nicht möglich — benötigte Funktionen im selben Skript definieren
eval / new Function(string)Aus Sicherheitsgründen gesperrt
Beliebige Java-KlassenAuch im EQL-Kompatibilitätsmodus dem Benutzercode nicht zugänglich
process / global / windowNicht definiert
WebSocket / EventSourceGesperrt — Nachrichtenempfang erfolgt über Trigger-Nodes

Ausführungsbeschränkung — es gibt keine​

Skripte unterliegen keiner Zeit-/Speicherbeschränkung

Ein älteres Dokument listete eine Tabelle mit Ausführungszeit 500 ms · Speicher 16 MB · Stack 1024 · Ausgabe 2 MB, aber keine von diesen vier wird angewendet.

  • In der Node-Konfiguration scheint timeout_ms verwendbar zu sein, aber der Script-Node liest diesen Wert nicht. (ScriptTransformNode · ScriptFilterNode lesen nur script und language.)
  • Auch der JS-Ausführungskontext hat keine Zeit-, Anweisungszahl- oder Speicherbeschränkung.

Daher belegt ein Skript wie while (true) {} den Worker-Thread ununterbrochen. Das flow-weite Limit von 30 Sekunden (flow_timeout_ms) wird geprüft, wenn die Ausführungsschleife die nächste Aufgabe entnimmt, sodass eine Endlosschleife innerhalb des Skripts diese Prüfung nie erreicht.

Verwenden Sie ausschließlich Skripte, die selbst enden. Vermeiden Sie Endlosschleifen·gigantische Wiederholungen·Anhäufung großer Strings und setzen Sie in Schleifen immer eine Obergrenze.

Was tatsächlich gesperrt ist — die Sicherheitssandbox​

Statt Zeit·Speicher wird das Berühren der Außenwelt eindeutig gesperrt.

ElementStatus
Zugriff auf Java-Klassen (z. B. Java.type)Gesperrt
Datei·Netzwerk-IOGesperrt
Thread-ErzeugungGesperrt
Native ZugriffeGesperrt
Experimentelle OptionenGesperrt
Zugriff auf Host-ObjekteNur solche in der Whitelist

Bei externen Aufrufen tun Sie dies nicht im Skript, sondern trennen Sie es in einen dedizierten Node wie flow_http_request — im Skript funktioniert es sowieso nicht, und beim dedizierten Node gilt timeout_ms tatsächlich.

Verteilen Sie aufwändige Verarbeitung auf mehrere Nodes statt auf ein einzelnes Skript zu konzentrieren.

Rückgaberegel von msg​

// flow_script_transform 의 두 가지 모드
// 1) mutate 모드 (기본) — msg 객체를 직접 수정, 마지막에 msg 또는 아무 값 반환
data.foo = 'bar';
msg

// 2) return 모드 — 완전히 새 객체로 교체
return {
type: msg.type,
originator: msg.originator,
data: { ...data, foo: 'bar' },
metadata: msg.metadata
};

Standardzeit·Locale​

ElementVerhalten
Server-SystemzeitzoneUTC (direkte Verwendung von epoch ms empfohlen)
Anzeige koreanischer ZeittoLocaleString('ko-KR', { timeZone: 'Asia/Seoul' })
Zeitberechnung koreanischer Zeitnew Date(ts + 9*3600000).getUTCHours() oder obige Locale
Timestamp-Einheit 0 SekundenMath.floor(Date.now() / 1000) * 1000

Speichersichere Erstellungsmuster​

Script-Nodes haben ein Speicherlimit von 16 MB, aber wenn sich in häufig aufgerufenen Nodes kleine Speicherlecks ansammeln, steigt die GC-Belastung der Engine erheblich. Vermeiden Sie folgende Muster.

Anti-Pattern 1 — Closure hält große Daten fest​

// ❌ 나쁜 예 — 큰 배열을 변환 함수에 캡쳐
const heavy = data.records || []; // 1만 건
const summarize = (item) => heavy.find(r => r.id === item.id);
data.matched = data.targets.map(summarize);
msg
// ✅ 좋은 예 — 인덱스 미리 만들고 함수 안에서만 사용
const index = {};
(data.records || []).forEach(r => { index[r.id] = r; });
data.matched = data.targets.map(t => index[t.id]);
data.records = undefined; // 변환 후 큰 원본 제거
msg

Anti-Pattern 2 — Übergabe großer Arrays im Original​

// ❌ data.records 가 10,000 건이면 모든 후속 노드에서 메모리 차지
msg
// ✅ 필요한 통계만 남기고 원본 제거
data.summary = {
count: (data.records || []).length,
total: (data.records || []).reduce((s, r) => s + r.value, 0)
};
delete data.records;
msg

Anti-Pattern 3 — Tiefe Objektkopie​

// ❌ JSON.parse(JSON.stringify(obj)) 는 큰 객체에서 매우 느림
data.copy = JSON.parse(JSON.stringify(data.original));
// ✅ 얕은 복사 또는 필요한 필드만 직접 선택
data.summary = { id: data.original.id, name: data.original.name };

Anti-Pattern 4 — Regex-Explosion (Catastrophic Backtracking)​

// ❌ (a+)+b 형태의 중첩 그룹은 입력에 따라 지수 시간
const re = /^(a+)+b$/;
if (re.test(data.text)) ...
// ✅ 비포획 그룹 + atomic 그룹 패턴 또는 단순 매칭
const re = /^a+b$/;
if (re.test(data.text)) ...

Anti-Pattern 5 — Kumulationsvariable let außerhalb der Funktion​

// ❌ 함수 밖 let 은 매 노드 호출마다 0으로 리셋되지만, 의도와 다르게 동작 가능
let counter = 0;
data.items.forEach(() => counter++);
data.counter = counter;
// ✅ 명시적으로 함수 안에서 선언
data.counter = data.items.length; // 같은 결과, 더 명확

Anti-Pattern 6 — Verschachteltes try/catch mit unbegrenzten Versuchen​

// ❌ 실패해도 다시 던지지 않으면 그래프가 잘못된 분기로 이동
try {
riskyCall();
} catch (e) { /* 무시 */ }
msg
// ✅ 실패 의도면 throw, 정상 의도면 명시적으로 기록
try {
riskyCall();
data.status = 'OK';
} catch (e) {
data.status = 'ERROR';
data.error_msg = e.message;
}
msg

Eine im Skript geworfene (throw) Ausnahme geht in den Zweig FAILURE und die Nachricht bleibt erhalten. Externe IO-Nodes haben ihre eigene separate Verzweigung, umhüllen Sie diese also nicht mit try/catch.

Diagnose von Speicherdruck​

Es gibt keinen Code wie NODE_SCRIPT_OOM

Ein älteres Dokument nannte NODE_SCRIPT_OOM · FLOW_MSG_TRIMMED · ENGINE_GC_PRESSURE als Signale für Speicherdruck, aber das Produkt erzeugt solchen Code nicht. Es gibt weder ein Skript-Speicherlimit noch eine automatische Kürzung der Payload.

Beurteilen Sie Speicherdruck nicht anhand von Code, sondern anhand von Metriken und Symptomen.

Zu BeobachtendesDrucksignal
FLOW_EXECUTOR_DROPPED_COUNTBeginnt bei 0 anzusteigen — der Verarbeitungspool ist gesättigt und verwirft Nachrichten
FLOW_EXECUTOR_QUEUE_SIZESteigt kontinuierlich ohne abzunehmen
FLOW_EXECUTION_TIMEMaximalwert springt auf ein Vielfaches des Normalwerts
Server-LogsWarnungen work_queue full ... task dropped, FlowExecutor timeout
JVMSteigende GC-Zeit · steigende Heap-Nutzung

Wenn diese Signale auftreten, prüfen Sie zuerst Flows, die große Payloads verarbeiten, und stellen Sie sicher, dass im Skript keine großen String-Arrays angesammelt werden.


Mobiler Push-Benachrichtigungskanal​

Mit dem flow_send_push-Node werden Push-Benachrichtigungen an die mobile App des Operators gesendet.

Node-Optionen​

OptionTypStandardwertBeschreibung
to / to_fieldstring(mind. 1 erforderlich)Empfänger-Benutzer-ID (durch Komma getrennt) oder Payload-Pfad
title / title_fieldstring(mind. 1 erforderlich)Benachrichtigungstitel (max. 50 Zeichen empfohlen)
body / body_fieldtext(mind. 1 erforderlich)Inhalt (max. 120 Zeichen empfohlen)
priorityenumNORMALNORMAL / HIGH — HIGH wird auch auf dem Sperrbildschirm angezeigt
soundenumdefaultdefault / silent / benutzerdefinierter Ton
datajson{}Zusatzdaten, die die App verarbeiten soll (Payload-Limit 4 KB)
deep_linkstring—Bildschirm, der bei Tippen auf die Benachrichtigung geöffnet wird (z. B. pp://asset/MOTOR-001)
ttl_secint86400Aufbewahrungsdauer bei Nicht-Empfang (Sekunden) — bei Ablauf automatisch gelöscht

Automatische Weiterleitung nutzerspezifischer Tokens​

Wenn sich ein Operator zum ersten Mal in der mobilen App anmeldet, wird der Gerätetoken automatisch in Sicherheit → API-Authentifizierungstoken registriert. Im Flow müssen Sie das Token nicht direkt verwalten — geben Sie nur die Benutzer-ID an.

  • Wenn sowohl iOS- als auch Android-Token registriert sind, wird an beide Geräte gesendet
  • Ist ein Token ungültig (z. B. App gelöscht), wird die Registrierung automatisch aufgehoben

Einfaches Sendebeispiel​

[flow_on_asset_alarm]
↓ where priority='ERROR'
[flow_send_push]
to_field: "metadata.responsible_user"
title: "🚨 ${metadata.asset_id} 알람"
body_field: "data.band_message"
priority: HIGH
deep_link: "pp://alarm/view/${data.alarm_id}"

Mehrsprachiger Push​

// flow_script_transform — 사용자 로케일에 따라 본문 분기
const locale = metadata.user_locale || 'ko-KR';
const templates = {
'ko-KR': { title: '🚨 ${asset} 위험 알람', body: '값 ${value}, 즉시 점검 바랍니다.' },
'en-US': { title: '🚨 ${asset} Critical Alarm', body: 'Value ${value}, please inspect immediately.' },
'ja-JP': { title: '🚨 ${asset} 危険警報', body: '値 ${value}, 即時点検が必要です。' }
};
const tpl = templates[locale] || templates['ko-KR'];
data.push_title = tpl.title.replace('${asset}', metadata.asset_id).replace('${value}', data.value);
data.push_body = tpl.body.replace('${value}', data.value);
msg

Danach über flow_send_push mit title_field=data.push_title / body_field=data.push_body verwenden.

Zusammengefasste Gruppenbenachrichtigung (Inbox-Stil)​

Mehrere Alarme in einer Benachrichtigung zusammenfassen (im 5-Minuten-Takt):

[flow_on_asset_alarm]
↓
[flow_merge window=300s]
↓ (data.merged 배열)
[flow_script_transform — 요약 만들기]
↓ data.push_body="알람 N건: A자산, B자산, ..."
[flow_send_push]

Automatische Eskalation bei Abwesenheit des Benutzers​

30 Minuten nach nicht bestätigter Push-Benachrichtigung automatische Eskalation per SMS oder E-Mail.

[flow_on_asset_alarm priority=ERROR]
↓
[flow_send_push]
↓ SUCCESS
↓ data.alert_id = response_id
[flow_delay 1800s (30분)]
↓
[flow_http_request GET /api/alert/${alert_id}/status]
↓ (response_body.read=false 면)
[flow_script_filter (data.response_body.read === false)]
↓ TRUE
[flow_send_sms]
to_field: "metadata.responsible_phone"
text: "푸시 미확인 30분 경과: ${data.title}"

Empfohlene Begrenzung der Sendefrequenz​

PrioritätEmpfohlene Häufigkeit
HIGH (Sperrbildschirmanzeige)max. 5 pro Benutzer und Stunde — zur Vermeidung von Alarmmüdigkeit
NORMALmax. 20 pro Benutzer und Stunde

Verdrahten Sie den Node flow_throttle vor dem Versand, oder stabilisieren Sie Alarme derselben Anlage mit flow_debounce vor dem Versand.


Automatische Aktualisierung externer Authentifizierungstoken​

Muster zur automatischen Erneuerung ablaufender Tokens wie OAuth2 beim Aufruf externer Systeme.

Einfache Erneuerung — zeitbasiert (cron)​

[flow_schedule cron='0 */50 * * * ?'] ← 50분마다 (만료 1시간 전)
↓
[flow_http_request]
url: "https://auth.example.com/oauth2/token"
method: POST
body: "grant_type=client_credentials&client_id=${creds.client_id}&client_secret=${creds.client_secret}"
↓
[flow_script_transform]
↓ data.access_token = data.response_body.access_token
[flow_save_attributes] ← 자격 증명 저장소에 저장
target_id: "creds:erp_api"
attributes: {"access_token": "${data.access_token}", "expires_at": ${data.response_body.expires_in * 1000 + ts}}

Anschließend in flow_http_request eines anderen Flows:

Headers: Authorization: Bearer ${creds:erp_api.access_token}

Proaktive Erneuerung — bei Empfang von 401​

[main flow]
↓
[flow_http_request]
↓ SUCCESS → 정상 처리
↓ FAILURE
[flow_script_filter (response_status === 401)]
↓ TRUE
[flow_subflow target_flow_id="refresh-token"] ← 토큰 갱신
↓
[원래 노드로 루프] ← 갱신된 토큰으로 재시도

Verwendung des Refresh Tokens​

[flow_http_request]
url: "https://auth.example.com/oauth2/token"
method: POST
body: "grant_type=refresh_token&refresh_token=${creds.refresh_token}"
↓
[flow_script_transform]
// 새 access_token + 새 refresh_token (rotation)
data.access_token = data.response_body.access_token;
data.refresh_token = data.response_body.refresh_token;
data.expires_at = Date.now() + data.response_body.expires_in * 1000;
msg
↓
[flow_save_attributes]

Automatischer Alarm bei Erreichen des Token-Ablaufschwellenwerts​

[flow_schedule cron='0 0 * * * ?'] ← 매시
↓
[flow_jdbc_query]
sql: "SELECT id, expires_at FROM credentials WHERE expires_at < NOW() + INTERVAL '1 day'"
↓
[flow_split]
↓
[flow_send_email]
subject: "API 토큰 만료 임박: ${data.id}"
body: "${data.id} 토큰이 ${data.expires_at} 만료 예정입니다."

Empfohlener Speicherort für Anmeldedaten​

ArtEmpfohlener Speicherort
Statisch (kaum Änderungen)Speicher für Anmeldedaten unter System → Einstellungen
Dynamisch (automatische Erneuerung)Speicherung in Anlagen-Metadaten mit obigem Muster über flow_save_attributes
Nutzerspezifisches OAuthBildschirm Sicherheit → API-Authentifizierungstoken

Belassen Sie Anmeldedaten nicht im Klartext im Graphen, sondern schreiben Sie unbedingt in Form einer Referenz auf einen externen Speicher (${creds.x}). Auch bei Export/Import sind Klartext-Tokens nicht im JSON enthalten.


Wählen Sie über die Option language aus, welche Sprache verwendet werden soll (JS oder EQL).


Ausführungshistorie-Bildschirm​

Node-bezogene Ausführungsereignisse können in chronologischer Reihenfolge abgerufen werden.

Suchbedingungen​

ElementBeschreibung
ZeitAbfragezeitraum angeben
Level전체 / INFO / WARN / ERROR
Flow-IDFilter auf einen bestimmten Flow
Nachrichten-IDzur Verfolgung einer einzelnen Nachricht
Anzahlletzte 200/500/1.000 Einträge

Schnelle Zeitbereiche​

Über die Schaltflächen oben im Timeline-Panel sofort wechseln: 10분전 / 30분전 / 1시간전 / 6시간전 / 12시간전 / 전체기간.

Ergebnisspalten​

SpalteBeschreibung
LevelINFO / WARN / ERROR
ZeitZeitpunkt des Ereignisses
EreignisFLOW_START / NODE_IN / NODE_OUT / NODE_ERROR / FLOW_END
Flow-IDum welchen Flow es sich handelt
NodeNode-Anzeigename
Node-Typz. B. flow_script_transform
BeziehungSUCCESS / FAILURE / TRUE / FALSE / MATCH / NO_MATCH / DEFAULT / THROTTLED / EXHAUSTED (alle in Großbuchstaben)
NachrichtZusammenfassung von Nachrichtentyp · Subjekt · Beziehung · Verarbeitungszeit · Datenvorschau

Mit der Schaltfläche CSV herunterladen können Sie das aktuelle Abfrageergebnis exportieren.

Die Aufbewahrungsdauer der Ausführungshistorie beträgt 7 Tage. Falls Langzeitspeicherung benötigt wird, laden Sie in ein externes Log-System.


Allgemeiner Workflow​

  1. Neuen Flow erstellen — Schaltfläche 새 플로우 im Listenbildschirm → Name·Beschreibung eingeben
  2. Bearbeitungsbildschirm aufrufen — leere Canvas öffnet sich automatisch
  3. Trigger-Node platzieren — Trigger-Node aus der linken Palette ziehen
  4. Verarbeitungsnodes hinzufügen — in der Reihenfolge Filter → Transformation → Aktion platzieren und über Wires verbinden
  5. Node konfigurieren — jeden Node anklicken und Optionen im rechten Inspektor eingeben
  6. Speichern — Schaltfläche 저장 oben rechts (automatischer Snapshot wird angelegt)
  7. Testlauf — Ergebnis durch Einspeisen einer beliebigen Nachricht prüfen
  8. Bereitstellen — Über den Schalter 배포 aktivieren → automatische Ausführung bei eingehendem Trigger-Ereignis
  9. Überwachung — Prüfung über das Live-Debug-Panel und den Ausführungshistorie-Bildschirm

Beispiel-Flows​

Jedes Beispiel besteht aus Node-Verdrahtungsdiagramm + zentraler Node-Konfiguration + Verhaltensbeschreibung. Die Node-Konfiguration im JSON-Format entspricht 1:1 den Werten, die Sie im rechten Inspektor eingeben.

Beispiel 1: Automatische Erstellung von MES-Arbeitsaufträgen​

Pollt minütlich neue POs vom MES und wandelt sie in Arbeitsaufträge um.

[flow_schedule: 매분]
│
▼ TIMER
[flow_http_request: MES /api/po/list?status=NEW]
│
▼ SUCCESS
[flow_split: data → 각 PO별 메시지]
│
▼
[flow_script_transform: PO → WorkOrder 매핑]
│
▼
[flow_create_work_order]
│
├── SUCCESS → [flow_log: 워크오더 생성됨]
└── FAILURE → [flow_send_email: 실패 알림]

Node-Konfiguration

NodeZentrale Konfiguration
flow_schedulecron: 0 * * * * ? (jede Minute Sekunde 0)
flow_http_requestmethod: GET, url: https://mes.example.com/api/po/list?status=NEW, headers: {"Authorization":"Bearer ${MES_TOKEN}"}
flow_splitpath: data (in Array aufteilen)
flow_script_transformlanguage: JS, siehe Skript unten
flow_create_work_ordermaster_id_field: data.master_id, asset_id_field: data.asset_id, order_name_field: data.order_name, planned_quantity_field: data.planned_quantity, unit_of_measure_field: data.unit_of_measure, external_system_field: data.external_system, external_id_field: data.external_id
flow_send_emailto_field: metadata.alert_to, subject: [MES 동기화 실패] ${data.po}

Script-Transform-Beispiel

data.master_id = 'WO-MES-' + data.po;
data.order_name = data.product_name + ' (' + data.qty + ' ' + data.uom + ')';
data.asset_id = data.line_id || 'UNASSIGNED';
data.planned_quantity = String(data.qty); // Planmenge - eine Dezimalzahl größer 0
data.unit_of_measure = data.uom; // UN/ECE-Rec-20-Code (EA, KGM, LTR ...) - Pflicht, kein Standardwert
data.external_system = 'MES'; // ein externer Arbeitsauftrag wird über das Paar (System, Nummer) identifiziert
data.external_id = data.po;
data.due_date = data.delivery_date;
metadata.alert_to = 'ops@example.com';
msg

Beispiel 2: Anlagenbefehl-Veröffentlichung über externen Webhook​

Validiert eine von einem externen System per HTTP gesendete Payload und wandelt sie in einen internen Anlagenbefehl um.

[flow_on_webhook]
│
▼ WEBHOOK
[flow_script_filter: payload 검증]
│
├── TRUE
▼
[flow_publish_asset_command]
│
├── SUCCESS → [flow_log]
└── FAILURE → [flow_webhook_callback: 외부에 실패 통보]

Aufrufmethode: Senden Sie den JSON-Body an POST /webhook/flow/{flow_id}, dann wird der Trigger unverändert mit dem Inhalt in data ausgelöst (der alte /flow/webhook/… liefert 410).

Script-Filter-Beispiel

// 인증 토큰 일치 + 필수 필드 존재 검사
if (data.token !== 'EXPECTED_TOKEN') return false;
if (!data.asset_id || !data.cmd_key) return false;
true

Beispiel 3: Automatische Ausstellung dringender Arbeitsaufträge bei Alarm → Arbeitsauftrag​

Bei einem Alarm der Stufe ERROR oder höher wird für die übergeordnete Anlage automatisch eine dringende Wartungsauftrag-Order ausgestellt.

[flow_on_tag_alarm]
│
▼ ALARM
[flow_script_filter: priority = ERROR/CRITICAL]
│
├── TRUE
▼
[flow_change_originator: Tag → 상위 Asset]
│
▼
[flow_create_work_order: 긴급 정비]
│
└── SUCCESS → [flow_send_email: 정비 담당자]

Script-Filter-Beispiel

['ERROR', 'CRITICAL'].includes(data.priority)

Beispiel 4: Externe DB-Synchronisation — Massenregistrierung von Anlagen​

Pollt neue Anlagenzeilen aus einer Legacy-DB und registriert sie automatisch als Anlagen.

[flow_jdbc_poll: SELECT * FROM legacy_assets WHERE sync_status='NEW']
│
▼
[flow_script_transform: 컬럼 매핑]
│
▼
[flow_create_asset]
│
├── SUCCESS → [flow_jdbc_query: UPDATE legacy_assets SET sync_status='OK' WHERE id=?]
└── FAILURE → [flow_log: ERROR + flow_send_push]

Node-Konfiguration

NodeZentrale Konfiguration
flow_jdbc_polldsn: externe DB-Verbindung, sql: SELECT * FROM legacy_assets WHERE sync_status='NEW' LIMIT 100, interval_ms: 60000
flow_create_assetasset_id_field: data.legacy_id, asset_name_field: data.name, site_id_field: data.plant_code
flow_jdbc_querysql: UPDATE legacy_assets SET sync_status='OK' WHERE id=?, params_field: data.legacy_id

Beispiel 5: Automatischer Zustandsübergang des Arbeitsauftrags​

Automatischer Zustandsübergang eines Arbeitsauftrags anhand von Betriebs-/Stoppereignissen einer Anlage.

[flow_on_asset_event]
│
▼ ASSET_EVENT
[flow_switch: data.event_type 기준]
│
├── case "RUN" ─▶ [flow_start_work_order] ─▶ [flow_log]
├── case "STOP" ─▶ [flow_pause_work_order] ─▶ [flow_log]
├── case "DONE" ─▶ [flow_end_work_order] ─▶ [flow_log]
└── DEFAULT ─▶ [flow_noop]

Beispiel für Switch-Node-Cases

  • RUN: data.event_type === 'RUN'
  • STOP: data.event_type === 'STOP'
  • DONE: data.event_type === 'DONE' && data.qty_done >= data.qty_planned

Fehlgeschlagene Zustandsübergänge (falscher aktueller Zustand) werden automatisch an FAILURE geroutet, sodass die Verdrahtung sicher ohne separaten Filter erfolgen kann.

Beispiel 6: Automatische Anpassung des Alarmbands​

Passt die oberen/unteren Alarmgrenzen des Tags dynamisch anhand der Anlagenaggregation (z. B. 6-Stunden-Durchschnittswert) an.

[flow_on_asset_aggregation]
│
▼ ASSET_AGGREGATION
[flow_script_transform: 통계 → 임계값 산출]
│
▼
[flow_update_tag_alarm_band_numeric]
│
├── SUCCESS → [flow_log]
└── FAILURE → [flow_send_email: 운영자 알림]

Script-Transform-Beispiel

// 6h 평균 ± 3σ 를 임계값으로 사용
const mean = data.mean;
const stddev = data.stddev || 1;
data.tag_id = originator.id + '.TEMP';
data.hi = mean + 3 * stddev;
data.lo = mean - 3 * stddev;
data.hi_hi = mean + 4 * stddev;
data.lo_lo = mean - 4 * stddev;
data.use_alarm = true;
msg

Beispiel 7: Automatische Registrierung von Edge-Geräten​

Registriert neue OPC-Server-Informationen beim Empfang im Batch am Edge-Gerät.

[flow_on_webhook] (POST 본문에 OPC + 태그 목록)
│
▼
[flow_edge_opc_create]
│
▼ SUCCESS
[flow_split: data.tags 배열]
│
▼
[flow_edge_tag_create]
│
▼ SUCCESS (모든 태그 등록 완료 후)
[flow_edge_opc_start]
│
└── SUCCESS → [flow_log: 엣지 디바이스 가동]

Beispiel für Aufrufkörper

{
"type": "WEBHOOK",
"data": {
"opc_id": "OPC-LINE-A",
"endpoint": "opc.tcp://line-a.local:4840",
"tags": [
{ "tag_id": "MOTOR-001.SPEED", "address": "ns=2;s=Motor1.Speed" },
{ "tag_id": "MOTOR-001.TEMP", "address": "ns=2;s=Motor1.Temp" }
]
}
}

Beispiel 8: Erhöhung der Zuverlässigkeit externer APIs (Retry)​

Wendet Backoff-Retry auf gelegentlich fehlschlagende externe API-Aufrufe an und benachrichtigt den Operator, wenn die maximale Versuchszahl überschritten wird.

[flow_on_asset_event]
│
▼
[flow_http_request: 외부 ERP API]
│
├── SUCCESS → [flow_log]
└── FAILURE ─▶ [flow_retry]
│
├── SUCCESS ─▶ (다시 flow_http_request 로 루프 결선)
└── EXHAUSTED ─▶ [flow_send_email: 'ERP 동기화 N회 실패']

Retry-Node-Konfiguration

  • max_attempts: 5
  • backoff_ms: 2000
  • backoff_multiplier: 2.0 → Intervalle von 2, 4, 8, 16, 32 Sekunden

Beispiel 9: Routing von Plugin-Ereignissen (Benachrichtigung bei niedriger OEE)​

Sendet eine Push-Benachrichtigung an den Linienmanager, wenn der OEE-Wert unter den Schwellenwert fällt.

[flow_on_oee_event]
│
▼
[flow_script_filter: data.availability * data.performance * data.quality < 0.6]
│
├── TRUE
▼
[flow_template: '라인 ${originator.id} OEE ${data.oee_pct}%']
│
▼
[flow_send_push: 라인 매니저]

Template-Beispiel

  • body: 라인 ${originator.id} OEE ${data.oee_pct}% (목표 60% 미달, 주요 손실: ${data.top_loss})

Beispiel 10: Nachrichtenaufbereitungspipeline (Throttle + Debounce)​

Begrenzt hochfrequente Tag-Änderungen auf 1 Auslösung pro Minute und lässt zusätzlich nur bei 5 Sekunden ohne Änderung den Folgenode auslösen.

[flow_on_tag_point]
│
▼
[flow_throttle: max_msgs=1, window_ms=60000]
│
├── SUCCESS → [flow_debounce: window_ms=5000]
│ │
│ ▼
│ [flow_save_attributes]
└── THROTTLED → [flow_log: 차단됨]

Beispiel 11: Aufsummierung mehrerer Trigger (Merge)​

Fasst OEE/RAM/EMS-Ereignisse im 30-Sekunden-Takt zusammen und sendet sie als eine Berichtsnachricht.

[flow_on_oee_event] ─┐
[flow_on_ram_event] ─┼─▶ [flow_merge: window_ms=30000]
[flow_on_ems_event] ─┘ │
▼
[flow_script_transform: 요약 메시지 생성]
│
▼
[flow_send_email: 일일 요약]

Wenn Sie mehrere Trigger-Nodes im selben Flow platzieren, werden alle zu Einstiegspunkten. Im data.merged-Array von flow_merge werden alle innerhalb des Zeitfensters eingegangenen Nachrichten kumuliert.

Beispiel 12: Bündelung gemeinsamer Verarbeitung über Subflow​

Die gemeinsame Nachrichtenaufbereitungslogik (Duplikatsprüfung + Einheitenumwandlung + Speicherung) wird in einen separaten Flow ausgelagert und von mehreren Triggern aus aufgerufen.

Haupt-Flows (jeweils unabhängig)

[flow_on_tag_point] ─▶ [flow_subflow: target_flow_id=FLOW_00099]
[flow_on_asset_data] ─▶ [flow_subflow: target_flow_id=FLOW_00099]

Subflow FLOW_00099

(트리거 없음 — 호출 전용)
[flow_log: 'subflow in']
│
▼
[flow_check_existence_field: data.value 존재]
│
├── TRUE
▼
[flow_script_transform: 단위 변환]
│
▼
[flow_save_tag_point]

Ein Subflow kann auch ohne Trigger gespeichert werden und lässt sich ausschließlich für externe Aufrufe verwenden (beim Speichern erscheint eine Warnung).

Beispiel 13: Automatischer Versand eines Tagesberichts bei Schichtwechsel​

Sendet täglich zum Ende der Nachtschicht (z. B. 06:00 Uhr) eine E-Mail mit einer Zusammenfassung von Produktion·Qualität·Downtime von gestern bis heute.

[flow_schedule: 0 0 6 * * ?] (매일 06:00)
│
▼ TIMER
[flow_http_request: 내부 통계 API /api/report/daily]
│
▼ SUCCESS
[flow_script_transform: 본문 마크다운 생성]
│
▼
[flow_send_email]

Script-Transform-Beispiel

const r = data.report;
data.subject = `[${r.site_id}] ${r.date} 일일 운영 요약`;
data.body =
`■ 생산: ${r.qty_done}/${r.qty_planned} (${(100*r.qty_done/r.qty_planned).toFixed(1)}%)\n` +
`■ 가동률: ${r.availability}%\n` +
`■ 품질률: ${r.quality}%\n` +
`■ 다운타임 Top3:\n` +
r.downtimes.slice(0,3).map(d => ` - ${d.code} ${d.minutes}분`).join('\n');
msg

Beispiel 14: Automatische Aggregation der Downtime​

Beim Eingang eines Anlagen-STOP-Ereignisses wird die kumulierte Downtime je Schicht aktualisiert und bei Überschreiten des Schwellenwerts eine Benachrichtigung gesendet.

[flow_on_asset_event]
│
▼
[flow_msg_type_filter: type in [ASSET_EVENT]]
│
▼ TRUE
[flow_script_filter: data.event_type === 'STOP']
│
▼ TRUE
[flow_script_transform: 다운타임 분 단위 계산]
│
▼
[flow_save_attributes: 자산 누적 다운타임 갱신]
│
▼ SUCCESS
[flow_script_filter: data.shift_downtime_min > 30]
│
▼ TRUE
[flow_send_push: '시프트 다운타임 30분 초과']

Beispiel 15: Automatische Isolierung einer Linie bei Qualitätsmängeln​

Wenn bei einer Qualitätsprüfung 5 oder mehr aufeinanderfolgende Mängel gemeldet werden, wird an die Linien-Anlage ein Stoppbefehl ausgegeben und der Arbeitsauftrag unterbrochen.

[flow_on_asset_event] (event_type=QUALITY_FAIL)
│
▼
[flow_script_transform: data.consecutive_fail = (... + 1)]
│
▼
[flow_save_attributes]
│
▼ SUCCESS
[flow_script_filter: data.consecutive_fail >= 5]
│
▼ TRUE
[flow_publish_asset_command: cmd_key='STOP']
│
▼
[flow_abort_work_order: abort_code='QUALITY']
│
└── SUCCESS → [flow_send_email: 품질 매니저 + 라인 매니저]

Beispiel 16: Überschreitung des Energieschwellenwerts — Empfehlung zur vorübergehenden Stilllegung der Linie​

Wenn der stündliche Energieverbrauch der Linie das Budget überschreitet, wird dem Operator per SMS eine Empfehlungsnachricht gesendet.

[flow_on_ems_event]
│
▼
[flow_script_filter: data.power_kwh > data.budget_kwh * 1.2]
│
▼ TRUE
[flow_template: '${originator.id} 시간당 ${data.power_kwh}kWh (예산 ${data.budget_kwh}kWh 초과)']
│
▼
[flow_send_sms]
│
└── SUCCESS → [flow_save_attributes: 자산에 마지막 경고 시각 기록]

Beispiel 17: Bidirektionale Synchronisation externer Systeme — Spiegelung des Arbeitsauftragsstatus​

Synchronisiert den vom externen ERP eingehenden Status bidirektional mit dem internen Arbeitsauftragsstatus.

Abwärts (ERP → intern)

[flow_on_mqtt_subscribe: erp/work-order/status]
│
▼
[flow_script_transform: 메시지 → 도메인 매핑]
│
▼
[flow_switch: data.status]
│
├── case "STARTED" ─▶ [flow_start_work_order]
├── case "PAUSED" ─▶ [flow_pause_work_order]
├── case "DONE" ─▶ [flow_end_work_order]
└── DEFAULT ─▶ [flow_log: WARN]

Aufwärts (intern → ERP)

[flow_on_entity_event] (originator.entity_type=Order)
│
▼
[flow_msg_type_filter: type in [ENTITY_UPDATED]]
│
▼ TRUE
[flow_template: ERP 형식으로 변환]
│
▼
[flow_mqtt_publish: erp/work-order/status]

Um bei bidirektionaler Synchronisation eine Endlosschleife zu vermeiden, markieren Sie die Nachrichtenquelle mit einem Schlüssel wie metadata.source und filtern Sie selbst veröffentlichte Nachrichten in der Trigger-Stufe heraus.


Import/Export​

Sie können Flow-Definitionen als JSON serialisieren, um sie in andere Umgebungen zu übertragen oder zu sichern.

AktionOrtBeschreibung
ExportierenSchaltfläche 내보내기 oben im BearbeitungsbildschirmHerunterladen des gesamten Graphen + Nodes + Wires + Node-Konfiguration als JSON
ImportierenSchaltfläche 가져오기 oben im ListenbildschirmJSON-Text einfügen oder hochladen
Automatischer SnapshotAutomatisch beim SpeichernBeim Graph-Speichern versionsweise angelegt (für Rollback)

Import-Verhalten

  • Es wird immer eine neue Flow-ID ausgestellt (Verhinderung des Überschreibens bestehender IDs)
  • Auch Node-IDs werden neu vergeben, die Wire-Links werden automatisch neu zugeordnet
  • Der Flow direkt nach dem Import wird im Zustand aufgehoben angelegt; der Operator muss ihn nach Prüfung selbst bereitstellen

Fehlerbehandlung​

Node-Ebene​

  • Tritt während der Node-Verarbeitung eine Ausnahme auf, wird automatisch in die Relation FAILURE geroutet.
  • Ist kein Node an den FAILURE-Ausgang angeschlossen, wird die Nachricht verworfen (drop) und nur der Fehlerprotokolleintrag bleibt.
  • Nicht mit *_pattern übereinstimmende Nachrichten des Trigger-Nodes werden als SKIPPED behandelt, nicht an Folgenodes weitergegeben und auch nicht in den Verarbeitungs-/Fehlerzähler aufgenommen.
  • Alle Fehler werden im Live-Debug-Panel und im Ausführungshistorie-Bildschirm angezeigt.

Flow-Ebene​

ElementStandardwertBeschreibung
max_depth100Begrenzung der kumulierten Node-Besuche während der Verarbeitung einer Nachricht
max_revisit3Begrenzung der Wiederbesuche desselben Nodes (Vermeidung von Zyklus-Endlosschleifen)
flow_timeout_ms30.000Erzwungene Beendigung bei Überschreitung der Verarbeitungszeit

Retry externer IO-Nodes​

Externe IO-Nodes wie HTTP·Kafka·externe DB können über die Optionen retry_count / retry_delay_ms intern innerhalb des Nodes sofort erneut versuchen; bei Fehlschlag aller Versuche wird in die Relation FAILURE geroutet. Bei Bedarf an präziserem Backoff oder EXHAUSTED-Zweigbehandlung verwenden Sie separat den flow_retry-Node.


Betriebsdiagnose​

Administratoren können im Systemmenü den Status der Dispatch-Warteschlange der Flow-Engine einsehen (Workerbetrieb, Größe der Warteschlange, kumulierte Verarbeitungs-/Fehlschlags-/Drop-Anzahl, letzter Fehler).

Der Server prüft periodisch im Hintergrund die Last des Flow-Worker-Pools und protokolliert bei anhaltend hoher Last für eine bestimmte Zeit eine Zeile mit der Statusänderung (HEALTHY → DEGRADED → CRITICAL) im Betriebsprotokoll. Bei Erholung wird ein weiterer Erholungslog-Eintrag hinzugefügt.


Berechtigungen​

Für Flow wird kein separates Berechtigungsmodell eingeführt, sondern die bestehende Systemauthentifizierung/-berechtigung unverändert genutzt.

FunktionErforderliche Berechtigung
Listenabfrage / AusführungshistorienabfrageAlle authentifizierten Benutzer
Erstellen·Bearbeiten·Bereitstellen·Löschen von FlowsADMIN
Import/Export / Alle neu bereitstellenADMIN

Betriebsmuster (Recipes)​

Eine Bibliothek häufig verwendeter Verdrahtungsformen. Jedes Muster können Sie unverändert kopieren und als Ausgangspunkt für einen neuen Flow verwenden.

Muster 1 — Verarbeitung + Benachrichtigungszweig​

Doppelte Verzweigung: SUCCESS wird gespeichert, FAILURE wird zur Benachrichtigung.

[Action Node]
├── SUCCESS → [flow_log] / [flow_save_attributes] / ...
└── FAILURE → [flow_send_email] / [flow_send_push]

Muster 2 — Sicherer Retry​

Konfiguration mit Backoff + EXHAUSTED-Handler, damit externe IO robust gegen vorübergehende Fehler ist.

[risky_node] ─[FAILURE]→ [flow_retry] ─[SUCCESS]→ (risky_node 로 루프)
└[EXHAUSTED]→ [에러 핸들러]

Muster 3 — Lastblockierung durch Vorabfilter​

Reduziert den nachfolgenden Durchsatz durch vorheriges Filtern von Nachrichten mit *_pattern auf Trigger-Ebene. Nicht übereinstimmende Muster werden als SKIPPED behandelt und nicht in den Zähler aufgenommen.

[flow_on_tag_point] (옵션 tag_id_pattern: "MOTOR-*.SPEED")
│
▼
[필터/변환/액션 ...]

Muster 4 — Mehrfache Case-Verzweigung​

Verzweigung in mehrere Zweige je nach Status/Typ.

[flow_switch] (case별 boolean 표현식)
├── case A → [...]
├── case B → [...]
└── DEFAULT → [...]

Muster 5 — Fensterakkumulierung + einmaliges Emit​

Sammelt hochfrequente Eingaben über einen bestimmten Zeitraum und wandelt sie in eine Nachricht um.

[High-rate Trigger]
│
▼
[flow_merge: window_ms=10000] → data.merged 배열에 누적
│
▼
[flow_script_transform: 요약]
│
▼
[Action / 외부 발송]

Muster 6 — Retry + Umleitung nach Erreichen des Wiederholungslimits​

Wenn Retry beendet ist, Umleitung auf einen Backup-Pfad (andere API, Benachrichtigung, DB-Speicherung).

[Primary HTTP] ─[FAILURE]→ [flow_retry]
├─[SUCCESS] → (Primary HTTP)
└─[EXHAUSTED] → [Backup HTTP] ─[FAILURE]→ [flow_log/Email]

Muster 7 — Folgeaktion nach Domänenänderung​

Transformiert einen Tag-bezogenen Alarm auf die übergeordnete Anlagenebene und delegiert die Verarbeitung an die Anlage.

[flow_on_tag_alarm]
│
▼
[flow_change_originator: Tag → Asset]
│
▼
[자산 단위 액션 (Create Work Order / Publish Asset Event 등)]

Muster 8 — Kombination von Throttle + Debounce​

Throttle auf max. 1× pro Minute + Verarbeitung nur bei 5 Sekunden ohne Änderung.

[High-rate Trigger]
│
▼
[flow_throttle: max_msgs=1, window_ms=60000]
│
▼ SUCCESS
[flow_debounce: window_ms=5000]
│
▼
[Action]

Muster 9 — Modularisierung gemeinsamer Logik über Subflow​

Wenn mehrere Einstiegspunkte dieselbe Folgeverarbeitung (Validierung·Aufbereitung·Speicherung) teilen müssen, Auslagerung in einen Subflow.

메인1: [Trigger A] → [flow_subflow: target=FLOW_99]
메인2: [Trigger B] → [flow_subflow: target=FLOW_99]

서브 (FLOW_99): (트리거 없음)
[검증] → [정제] → [적재]

Muster 10 — Umleitung über direkten Trigger​

Um das Ergebnis eines anderen Flows als Eingabe eines nächsten Flows fließen zu lassen, mit flow_dds_publish im Domänenkanal veröffentlichen; der andere Flow empfängt denselben Nachrichtentyp als Trigger.

플로우 A: [...] → [flow_dds_publish: type=ASSET_EVENT, originator=...]
플로우 B: [flow_on_asset_event] → [...]

Anwendungsbeispiele (auf einen Blick)​

SzenarioAufbau
MES-Anbindungflow_schedule → flow_http_request → flow_script_transform → flow_create_work_order
Externe Weiterleitung von Ereignissenflow_on_asset_event → flow_msg_type_filter → flow_mqtt_publish
Datenaufbereitung·Speicherungflow_on_tag_point → flow_script_transform → flow_save_tag_point
Alarmautomatisierungflow_on_tag_alarm → flow_script_filter → flow_send_email + flow_create_work_order
Externe DB-Synchronisationflow_jdbc_poll → flow_script_transform → flow_create_asset
Webhook-Empfangflow_on_webhook → flow_script_filter → flow_publish_asset_command
Automatische Anpassung des Alarmbandsflow_on_asset_aggregation → flow_script_transform → flow_update_tag_alarm_band_numeric
Automatisierung des Arbeitsauftragsstatusflow_on_asset_event → flow_switch → flow_start/end/pause/resume_work_order
Verbesserung der API-Zuverlässigkeitflow_http_request ─FAILURE→ flow_retry ─SUCCESS→ Schleife / EXHAUSTED→ Benachrichtigung
Benachrichtigung bei niedriger OEEflow_on_oee_event → flow_script_filter → flow_template → flow_send_push
Massenregistrierung von Edgesflow_on_webhook → flow_edge_opc_create → flow_split → flow_edge_tag_create → flow_edge_opc_start
Hochfrequente Aufbereitungflow_throttle → flow_debounce → Folge
Aufsummierung mehrerer EreignisseMehrfach-Trigger → flow_merge → Zusammenfassungstransformation → Versand

Schrittweiser Debugging-Leitfaden​

Ein Standardverfahren, dem Sie folgen sollten, wenn ein Flow nicht wie beabsichtigt funktioniert.

Schritt 1 — Auslösestatus prüfen​

Prüfen Sie im Listenbildschirm, ob die Ausführungsanzahl des betreffenden Flows zunimmt.

BeobachtungBedeutung·nächste Maßnahme
Zähler bei 0Trigger löst nicht aus. Prüfen Sie den Bereitstellungsstatus des Flows + die Trigger-Node-Verdrahtung + die Option *_pattern
Zähler steigt, aber auch Fehler steigtFehlschlag im Aktions-Node. Weiter zu Schritt 2
Zähler steigt, aber Folgeverarbeitung fehltVerzweigungsverdrahtung fehlt. Alle Ausgänge wie FAILURE/THROTTLED/EXHAUSTED prüfen

Schritt 2 — Node-bezogenen Ablauf über Live-Debug prüfen​

Öffnen Sie den Bearbeitungsbildschirm und aktivieren Sie das Live-Debug-Panel (Aktualisierung alle 2 Sekunden).

BeobachtungBedeutung
Leuchtanzeige eines bestimmten Nodes bleibt grauNachricht kommt nicht an — im vorherigen Node in Zweig FAILURE oder vom Filter blockiert
Leuchtanzeige rot + ERROR-ZeileAusnahme während der Node-Verarbeitung. Feld data.error der Nachricht und NODE_ERROR-Ereignis in /flow/log prüfen
Leuchtanzeige grün, aber nächster Node grauRelation-Label der Ausgabe stimmt nicht überein. Prüfen, ob das Wire-Label exakt mit der Ausgangs-Relation des Nodes (SUCCESS/TRUE usw.) übereinstimmt

Schritt 3 — Nachrichten über den Ausführungshistorie-Bildschirm verfolgen​

Verfolgen Sie im Bildschirm /flow/log anhand der Nachrichten-ID den gesamten Ablauf einer einzelnen Nachricht.

  • Im Nachrichten-ID-Filter die im Live-Debug beobachtete msg_id eingeben
  • Sortierung chronologisch in der Reihenfolge FLOW_START → NODE_IN → NODE_OUT → FLOW_END
  • Bei sichtbarem NODE_ERROR liegt die Ursache im error_message dieses Nodes

Schritt 4 — Node-Konfiguration prüfen​

Häufige Fehler:

FehlerPrüfung
Tippfehler im Pfad *_fieldStimmt data.tag_id? Ist es metadata.tag_id? Tatsächlichen Schlüssel über die Nachrichtenvorschau des Live-Debug prüfen
Vorlagenvariable ${...} nicht substituiertPrüfen, ob der Variablenpfad in der Nachricht existiert, keine Tippfehler
Timeout bei externer IOtimeout_ms erhöhen. Antwortzeit des externen Systems selbst
Berechtigung·AuthentifizierungsheaderPrüfen, ob das JSON-Format von headers korrekt ist und das Token noch gültig ist

Schritt 5 — Isolierter Test​

Verschieben Sie den problematischen Node isoliert in einen neuen temporären Flow und lösen Sie mit Testlauf genau eine Nachricht aus, um das Ergebnis isoliert zu verifizieren. Funktioniert er normal, liegt der Verdacht bei der Verdrahtung des ursprünglichen Flows bzw. der Form der Nachricht aus der vorherigen Stufe.

Schritt 6 — Reproduktion nach Zählerreset​

Wenn Sie nach dem Zurücksetzen aller Zähler genau eine Nachricht auslösen, um mit einer sauberen Statistik zu reproduzieren, wird das Problem klarer erkennbar.


Häufig auftretende Probleme​

SymptomUrsache·Maßnahme
Trigger löst nicht ausPrüfen, ob der Flow im Zustand Bereitstellen ist und ob *_pattern des Trigger-Nodes nicht zu eng ist. Bei Schedule-/externen Abo-Nodes erneut versuchen nach Alle neu bereitstellen
Live-Debug ist leerPrüfen, ob der Nachrichtenzähler nicht steigt — nicht übereinstimmende Trigger-Muster (SKIPPED) werden nicht im Zähler gezählt. Auch prüfen, ob der Pausenschalter oben im Panel aktiviert ist
Zählerwerte akkumulieren sich anormalMit der Schaltfläche Alle Zähler zurücksetzen oben rechts in der Node-Konfiguration das Statistikfenster zurücksetzen
Dieselbe Nachricht wird wiederholt verarbeitetZyklus vermuten. Wiederbesuch desselben Nodes ist nur innerhalb von max_revisit (Standard 3-mal) erlaubt. Mit flow_subflow trennen und Eingabemenge über flow_throttle/flow_debounce anpassen
Externer Systemaufruf schlägt gelegentlich fehlBackoff-Retry über die Optionen retry_count/retry_delay_ms oder den Node flow_retry verdrahten
Schedule funktioniert nach Import nichtAlle neu bereitstellen oben im Listenbildschirm ausführen
Nach Update-Node-Ausführung bleiben manche Felder unverändertBeabsichtigtes Verhalten. Der Update-Node aktualisiert nur die eingegebenen Felder und behält den Rest bei. Vollständige Aktualisierung: Kombination Delete + Create
Create-Node schlägt mit NOT-NULL-Fehler fehlPrüfen, ob der Pfad der dynamischen Option *_field in der Node-Konfiguration tatsächlich in der Nachricht existiert. Manche NOT-NULL-Spalten werden automatisch ergänzt, aber Kern-IDs (asset_id, tag_id usw.) müssen Sie selbst befüllen
flow_kafka_publish / flow_mqtt_publish wird nicht veröffentlichtVerbindungsinformationen zum externen Broker (bootstrap_servers/broker_url) und Topic-Berechtigung prüfen. Mit flow_log daneben verdrahten, um zu prüfen, ob die Nachricht kurz vor der Veröffentlichung ankommt
flow_http_request erhält keine Antworttimeout_ms (Standard 5000) erhöhen und den Body direkt im Format ${msg.data.x} in body_template angeben. Die Antwort wird in data.response_status / data.response abgelegt
flow_retry wird nicht erneut versuchtFall einer fehlerhaften Verdrahtung. Der SUCCESS-Ausgang von flow_retry muss wieder zum ursprünglichen fehlgeschlagenen Node zurückgeführt werden, damit ein Retry erfolgt (siehe Muster 2 unten)
Eine Zeile wie flow_jdbc_poll kommt jedes Mal erneut hereinDie Bedingung WHERE der Polling-SQL muss die Statusaktualisierung nach der Verarbeitung enthalten (z. B. WHERE sync_status='NEW' + am Ende desselben Flows UPDATE ... sync_status='OK' mit flow_jdbc_query)
Der Node zur direkten Alarmauslösung ist nicht auffindbarBeabsichtigter Ausschluss. Alarme sollten nur über den flow_create_alarm_config-Pfad entstehen, damit die Konsistenz der Alarmhistorie gewahrt bleibt
Script-Node schlägt mit Zugriffsfehler auf Java class fehlIn der Skript-Sandbox gesperrt. Verdrahten Sie für externe Aufrufe einen separaten externen Anbindungs-Node
Beim Zustandsübergangsnode des Arbeitsauftrags kommt nur FAILURE herausDer aktuelle Zustand ist nicht der Ausgangszustand, von dem ein Übergang möglich ist. Beispiel: flow_pause_work_order funktioniert nur im Zustand START. Vorher mit flow_check_existence_field / flow_script_filter den Zustand prüfen
Testlauf hat funktioniert, aber der Graph blieb geändertDer Testlauf löst immer die gespeicherte Version aus. Um Änderungen zu prüfen, zuerst speichern → dann Testlauf
Importierter Flow ist inaktivBeabsichtigtes Verhalten. Nach Prüfung selbst den Schalter Bereitstellen aktivieren

Häufig gestellte Fragen (FAQ)​

Häufig gestellte Fragen von Operatoren bei der erstmaligen Nutzung von Flow.

F. Kann ein Flow mehrere Trigger haben? A. Ja. Wenn Sie im selben Flow mehrere Trigger-Nodes platzieren, werden alle zu Einstiegspunkten und lösen unabhängig aus. In Kombination mit flow_merge können Sie mehrere Ereignistypen in eine gemeinsame Folgeverarbeitung zusammenführen.

F. Kann ich auch einen Flow ohne Trigger erstellen? A. Ja. Beim Speichern erscheint eine Warnung, aber gespeichert wird trotzdem. Sie können ihn als „Bibliothek“ verwenden, die nur über Testlauf oder den flow_subflow-Aufruf eines anderen Flows ausgelöst wird.

F. Kann eine Nachricht mehrere Nodes gleichzeitig durchlaufen? A. Ja. Wenn Sie mehrere Wires am Ausgangsport eines Nodes verbinden, wird dieselbe Nachricht gleichzeitig verzweigt und an alle Folgenodes weitergeleitet.

F. Kann ich im Transformationsnode selbst eine Nachricht erzeugen und in eine andere umwandeln? A. Ja. In flow_script_transform können Sie msg.type, msg.originator, msg.data, msg.metadata alle frei ändern. Auch wenn die Nachricht selbst so aussieht, als sei sie ein anderer Triggertyp, ruft sie dadurch keinen anderen Flow automatisch auf (die ursprüngliche Trigger-Zuordnung bleibt erhalten). Um einen anderen Flow aufzurufen, verwenden Sie flow_subflow oder flow_dds_publish.

F. Wie viele automatische Snapshots werden aufbewahrt? Kann ich selbst wiederherstellen? A. Bei jedem Graph-Speichern wird automatisch ein Snapshot angelegt; die Aufbewahrungsrichtlinie folgt der Konfiguration der Betriebsumgebung. Eine UI zur direkten Wiederherstellung im Bildschirm wird nicht angeboten; bei Bedarf können Sie den Administrator bitten, auf eine bestimmte Version zurückzusetzen. Am sichersten ist es, vor Änderungen die JSON-Datei per 내보내기 extern aufzubewahren.

F. Wie lange wird die Ausführungshistorie aufbewahrt? A. Standardmäßig 7 Tage. Falls Langzeitspeicherung nötig ist, laden Sie über flow_kafka_publish oder flow_jdbc_query in ein externes Log-System.

F. Ich möchte nur die Statistik eines Flows separat zurücksetzen. A. Verwenden Sie oben rechts in der Node-Konfiguration des Bearbeitungsbildschirms Fehlerzähler zurücksetzen (nur Fehler) oder Alle Zähler zurücksetzen (alles). Andere Flows sind davon nicht betroffen.

F. Ich möchte einen Flow in eine andere Umgebung (Entwicklung/Staging/Produktion) verschieben. A. Laden Sie das JSON über 내보내기 im Bearbeitungsbildschirm herunter und laden Sie es über 가져오기 im Listenbildschirm der Zielumgebung hoch. Ein importierter Flow wird immer mit neuer ID + im Zustand aufgehoben angelegt, sodass der Operator ihn nach Prüfung selbst bereitstellen kann.

F. Dieselbe Payload wird zweimal verarbeitet. Wie kann ich das verhindern? A. Engen Sie den Trigger mit *_pattern ein oder begrenzen Sie die Frequenz mit flow_throttle/flow_debounce. Bei externen Eingaben (Webhook·MQTT) können Sie auf der Senderseite einen Idempotenz-Schlüssel setzen und Duplikate über flow_check_existence_field oder einen nachrichten-ID-basierten Filter herausfiltern.

F. Ist eine Zyklus-(Schleifen-)Verdrahtung sicher? A. Ein beabsichtigter Zyklus wie flow_retry ist sicher. Andere Zyklen werden automatisch durch max_revisit (Standard 3-mal) blockiert. Während des Betriebs empfiehlt es sich jedoch, den Ablauf mit flow_log zu visualisieren, um unbeabsichtigte Zyklen frühzeitig zu erkennen.

F. Werden Flow-Änderungen in Echtzeit wirksam? A. Beim Graph-Speichern sofort wirksam. Allerdings müssen Trigger mit eigenem Scheduler wie Schedule·externes Abonnement·externes DB-Polling über Alle neu bereitstellen oder durch Aufheben→Bereitstellen erneut registriert werden.

F. Kann ich die ID eines bereits registrierten Nodes ändern? A. Die Node-ID wird vom System automatisch vergeben. Der Anzeigename kann im Node-Konfigurationsformular geändert werden; im Live-Debug·in der Ausführungshistorie wird der Anzeigename verwendet.

F. Kann ein Benutzer ohne Berechtigung versehentlich einen Flow ändern? A. Erstellen·Bearbeiten·Bereitstellen·Löschen von Flows benötigt ADMIN-Berechtigung. Normale Benutzer können nur die Liste und die Ausführungshistorie einsehen.


Best Practices für den Betrieb​

Grundsätze, die Sie beim sicheren Betrieb von Flows in der Produktion beachten sollten.

Lastmanagement​

  • Filtern Sie in der Trigger-Stufe mit *_pattern vorab, um den Folgeverarbeitungsaufwand zu reduzieren. Tag-Datenpunkte mit mehreren zehntausend Eingängen pro Minute sind der teuerste Einstiegspunkt.
  • Kombinieren Sie Aufrufe externer Systeme (flow_http_request/flow_jdbc_query usw.) mit flow_throttle / flow_debounce, um die externe Last zu steuern.
  • Wenn mehrere Folgenodes an dieselbe Eingabe hängen sollen, trennen Sie diese mit flow_subflow, um die Gesamtzahl der Nodes im Graphen zu senken. Je mehr Nodes, desto höher auch die Polling-Kosten des Live-Debug.
  • Aktivieren Sie den Debug-Modus nur während der Betriebsverifizierung. Je mehr geladen wird, desto schneller füllt sich das 7-Tage-Fenster der Ausführungshistorie.

Sichere Erstellung​

  • Verdrahten Sie bei allen Aktions-Nodes unbedingt die FAILURE-Verzweigung (mindestens flow_log). Ist FAILURE leer, wird die Nachricht still verworfen, was die Vorfallverfolgung erschwert.
  • Kombinieren Sie externe IO-Nodes, wenn möglich, mit flow_retry, um vorübergehende Störungen abzufangen.
  • Update-Nodes aktualisieren nur die eingegebenen Felder (Teilaktualisierung). Für vollständiges Überschreiben verwenden Sie die Kombination Delete + Create.
  • Graphen ohne Trigger-Node sind nur für manuellen Testlauf. Prüfen Sie die Warnung beim Speichern, um nicht versehentlich den Trigger zu vergessen.
  • Erstellen Sie Zyklen (Verdrahtung zurück zum gleichen Node) nur bewusst in Form wie flow_retry; in anderen Fällen schützt max_revisit, aber visualisieren Sie verdächtige Graphen mit flow_log.

Änderungsverfahren (Change Management)​

Empfohlene Reihenfolge bei der Änderung eines produktiven Flows.

  1. Backup — Aktuellen Graphen über 내보내기 im Bearbeitungsbildschirm als JSON-Datei herunterladen und aufbewahren (auch wenn automatische Snapshots angelegt werden, ist externe Aufbewahrung sicherer).
  2. In Kopie oder neuem Flow arbeiten — Bearbeiten und verifizieren Sie Änderungen eher in einem neuen Flow (oder einer per Import erstellten Kopie) als am laufenden Flow direkt.
  3. Testlauf — Injizieren Sie direkt JSON-Nachrichten, um jede Verzweigung (SUCCESS/FAILURE/EXHAUSTED usw.) einmal auszulösen und das Ergebnis in der Ausführungshistorie zu prüfen.
  4. In Produktion übernehmen — Verifiziertes Graph-JSON über 내보내기 → in der Produktionsumgebung über 가져오기 → nach Prüfung durch den Operator den Bereitstellen-Schalter aktivieren.
  5. Rollback bei Problemen — Sofort mit dem Aufheben-Schalter deaktivieren. Da automatische Snapshots angelegt sind, kann der Entwickler bei Bedarf auf eine vorherige Version zurücksetzen.

Nutzung von Zählern·Statistik​

  • Falls die Verarbeitungstrend-Sparkline im Listenbildschirm plötzlich flach wird, prüfen Sie auf nicht ausgelösten Trigger oder mögliche SKIPPED-Behandlung.
  • Ist das Fehlerquote-Donut-Diagramm anormal, vermuten Sie den *_field-Pfad in der Node-Konfiguration. Fehlt der Schlüssel in der Nachrichten-Payload, schlägt es häufig fehl.
  • Nach der Betriebsverifizierung setzen Sie mit Alle Zähler zurücksetzen das Statistikfenster zurück, um die normale Baseline neu zu messen.

Notfallreaktionsverfahren​

Schrittweises Verfahren, das Sie bei einem Problem im Betrieb schnell anwenden sollten.

Szenario 1 — Ein bestimmter Flow läuft Amok (Nachrichtenexplosion)​

Symptom: Die Ausführungszahl eines Flows steigt um das Zehn- bis Hundertfache gegenüber dem Normalwert, begleitet von zunehmenden Fehlern

Maßnahme

  1. Sofort den betreffenden Flow über den Aufheben-Schalter deaktivieren (1 Sekunde im Listenbildschirm)
  2. Im Live-Debug-Panel·in der Ausführungshistorie prüfen, welcher Trigger die Explosion verursacht hat
  3. Die Option *_pattern des Trigger-Nodes einengen oder direkt danach flow_throttle / flow_debounce verdrahten
  4. Falls nötig, den Nachrichtentyp mit flow_check_existence_field oder flow_msg_type_filter eingrenzen
  5. Nach der Korrektur mit Testlauf reproduzieren → nach normaler Bestätigung Bereitstellen wieder aufnehmen

Szenario 2 — Massenausfall durch Störung eines externen Systems​

Symptom: Gleichzeitige Fehleranhäufung bei externen IO-Nodes wie HTTP/Kafka/externer DB

Maßnahme

  1. Bei breiter Auswirkung die betroffenen Flows in Masse aufheben (Massenauswahl im Listenbildschirm, dann Massenaufhebung)
  2. Wiederherstellung des externen Systems bestätigen
  3. Bei externen IO-Nodes ohne flow_retry-Verdrahtung eine solche hinzufügen
  4. Bei verlangsamter Antwort des externen Systems timeout_ms anpassen
  5. Je nach Betriebsumgebung nach Alle neu bereitstellen die Bereitstellung wieder aufnehmen

Szenario 3 — Endlosschleife durch Zyklus​

Symptom: Eine einzelne Nachricht durchläuft ständig denselben Node, akkumulierte Verarbeitungszeit

Maßnahme

  1. Der max_revisit-Schutz blockiert automatisch nach maximal 3 Wiederbesuchen, aber zur Betriebssicherheit aufheben und prüfen
  2. Zyklus im Graphen visuell verfolgen (im Bearbeitungsbildschirm den Wires folgen)
  3. Bei beabsichtigter Schleife (flow_retry) prüfen, ob max_attempts angemessen ist
  4. Bei unbeabsichtigtem Zyklus Verdrahtung entfernen oder Verzweigung mit flow_check_relation hinzufügen
  5. Nach der Korrektur Alle Zähler zurücksetzen → erneut bereitstellen

Szenario 4 — Verdacht auf Datenbeschädigung (fehlerhafte automatische Aktualisierung)​

Symptom: Domänendaten wurden durch Automatisierung entgegen der Absicht aktualisiert

Maßnahme

  1. Sofort den betreffenden Flow aufheben
  2. Externes JSON-Backup des vorherigen Graphen oder vorherige Version aus dem automatischen Snapshot prüfen (mit Unterstützung des Administrators)
  3. Graph analysieren: unbeabsichtigte Update-Node-Verdrahtung·fehlerhaften *_field-Pfad·Skript-Transformationsfehler prüfen
  4. Betroffene Domänendaten separat über das Backoffice-Verfahren korrigieren
  5. Den korrigierten Graphen mit Testlauf verifizieren und erneut bereitstellen

Szenario 5 — Stopp während Systeminspektion·Wartung​

Symptom: Externe IO-Aufrufe sollen während der Wartungszeit des externen Systems vorübergehend gestoppt werden

Maßnahme

  1. Betroffene Flows in Masse aufheben (Mehrfachauswahl in der Liste)
  2. Nach Ende der Wartung Bereitstellung wieder aufnehmen
  3. Bei Triggern mit eigenem Scheduler (Schedule·externes MQTT-Abonnement·externes DB-Polling) einmal Alle neu bereitstellen ausführen, um die korrekte Registrierung zu bestätigen

Szenario 6 — Live-Debug-Ladewarteschlange voll​

Symptom: Die Größe der Ladewarteschlange in der Betriebsdiagnoseseite liegt nahe am Schwellenwert, Drop-Anzahl steigt

Maßnahme

  1. Reduzieren Sie die Anzahl der Flows mit aktiviertem Debug-Modus und die Ladung (verifizierte Flows: Debug-Modus AUS)
  2. Reduzieren Sie den Folgeverarbeitungsaufwand selbst mit *_pattern in der Trigger-Stufe
  3. Wenn das System automatisch in den Erholungsmodus wechselt, wird vom Last-Watchdog eine Zeile mit DEGRADED/CRITICAL protokolliert — teilen Sie diese mit dem Administrator

In allen Szenarien gilt die Reihenfolge sofort aufheben → Ursache klären → korrigieren → verifizieren → erneut bereitstellen. Siehe auch das Änderungssicherheitsverfahren.


Sicherheit·Umgang mit sensiblen Informationen​

Da Flow sensible Ein-/Ausgaben wie externe API-Aufrufe·E-Mail-/SMS-Versand·Webhook-Empfang verarbeitet, beachten Sie folgende Grundsätze.

Token·Anmeldedaten​

  • Geben Sie API-Token·Passwörter nicht im Klartext direkt in die Node-Konfiguration ein. Verwenden Sie die Substitution über Umgebungsvariablen in Form von ${ENV_VAR}, um sie aus dem geheimen Speicher der Betriebsumgebung einzuspeisen.
  • Trennen Sie die Token-Position im headers JSON, um Tokens in der Produktionsumgebung möglichst als Umgebungsvariable zu isolieren.
// 권장
{ "Authorization": "Bearer ${MES_TOKEN}" }

// 비권장
{ "Authorization": "Bearer eyJhbGciOi..." }

Schutz des Webhook-Einstiegspunkts​

flow_on_webhook ist ein interner Einstiegspunkt, der von authentifizierten Benutzern aufgerufen wird; wenn Sie ihn nach außen exponieren, verdrahten Sie unbedingt einen Payload-Validierungsfilter.

// flow_script_filter — 토큰 + 필수 필드 검사
if (data.token !== '${WEBHOOK_TOKEN}') return false;
if (!data.asset_id || !data.cmd_key) return false;
true

Maskierung sensibler Daten​

Im Live-Debug-Panel und in der Ausführungshistorie wird eine Nachrichtenvorschau angezeigt. Maskieren Sie persönliche Daten (Name·Kontakt·Konto) und Tokens unmittelbar vor der Speicherung.

// 디버그/로그 적재 직전 변환
data.email_masked = data.email
? data.email.replace(/(.{2}).+(@.+)/, '$1***$2') : null;
delete data.email;
delete data.token;
msg

Verarbeitung des Response-Bodys externer IO​

Bei flow_http_request wird der gesamte data.response-Response-Body geladen. Enthält die Antwort sensible Daten, extrahieren Sie sofort im Folgetransformationsnode nur die benötigten Schlüssel und entfernen Sie das Original.

// 응답에서 필요한 필드만 보존
data = { id: data.response_obj.id, status: data.response_obj.status };
msg

Isolierung von Script-Nodes​

Script-Nodes werden in einer sicheren Sandbox ausgeführt, wobei Datei-, Netzwerk- und beliebiger Klassenzugriff gesperrt sind. Verdrahten Sie bei Bedarf externer Aufrufe unbedingt einen separaten externen Anbindungs-Node.


Flow-Metriken und Alarme​

Automatisch erfasste Kennzahlen während des Flow-Betriebs, wo Sie sie sehen und wie Sie Alarme darauf setzen.

Flow-bezogene KPIs​

In jeder Zeile des Listenbildschirms (/flow/index) werden folgende KPIs angezeigt.

KennzahlBedeutungAnormales Signal
GesamtausführungsanzahlAnzahl der Durchläufe durch den Graphen infolge eines Trigger-Auslösens (Summe von Erfolg/Fehlschlag)Starker Rückgang gegenüber normal → Trigger tot / starker Anstieg → Amoklauf
FehleranzahlAnzahl der Fälle, die an irgendeinem Node des Graphen in den FAILURE-Zweig gefallen sindAb 5 % des Gesamtwerts prüfen
Fehlerquote에러 / 전체 × 100Bei Überschreiten eines bestimmten Schwellenwerts Alarm setzen
Letzte AusführungZeitpunkt der jüngsten AuslösungNur OK, wenn „mehr als 5 Minuten keine Auslösung“ normal ist
Durchschnittliche VerarbeitungszeitDurchschnittliche ms, die eine Nachricht benötigt, um den ganzen Graphen zu durchlaufenÄndert sich stark bei Hinzufügen/Entfernen externer IO-Nodes
Trend der letzten Verarbeitungszeit5-Minuten-Sparkline — Live-Debug-PanelBei Spikes Antwortzeit des externen Systems prüfen

Node-bezogene KPIs​

Beim Klick auf einen Node im Bearbeitungsbildschirm wird unten rechts am Node Folgendes angezeigt.

[Node Name]
처리 999 · 에러 3 · 평균 12ms · 최근 18ms
PositionAnzeige
Obere LeuchtanzeigeGrau (wartend) / Grün (in Verarbeitung) / Rot (Fehler)
Untere Beschriftung처리 N · 에러 M · 평균 Xms · 최근 Yms

4 Node-Statistiken​

ZählerBedeutung
VerarbeitungAnzahl der in diesen Node eingegangenen und über normale Verzweigung ausgegangenen Nachrichten
FehlerAnzahl der FAILURE-Verzweigungen oder Ausnahmen
Durchschnittliche VerarbeitungszeitEigene Verarbeitungs-ms des Nodes (inkl. externer IO)
Letzte VerarbeitungszeitVerarbeitungs-ms des jeweils letzten Eintrags

Systemweite Metriken​

Die Metriken der gesamten Flow-Engine finden Sie im Bildschirm System → Monitoring.

Die Metriken werden unter der JMX-Domain plantpulse.core.engine als folgende fünf freigegeben.

MetrikArtBedeutungAnsicht
FLOW_EXECUTOR_QUEUE_SIZEGaugeGröße der Warteschlange des Flow-AusführungspoolsBei kontinuierlicher Anhäufung folgt die Verarbeitung dem Eingang nicht
FLOW_EXECUTOR_ACTIVE_COUNTGaugeAnzahl aktiver Threads des AusführungspoolsBei Anlehnung an die Poolgröße Sättigung
FLOW_EXECUTOR_DROPPED_COUNTGauge (kumuliert)Kumulierte Anzahl verworfener Tasks bei PoolsättigungUngleich 0 bedeutet Nachrichtenverlust — der zuerst zu prüfende Wert
FLOW_DEBUG_QUEUE_SIZEGaugeGröße der Warteschlange für Debug-EreignisseWird groß, wenn viele Flows mit Debug-Modus aktiviert sind
FLOW_EXECUTION_TIMETimerVerteilung der Verarbeitungszeit pro FlowDurchschnitt·Maximum verfolgen
Es gibt keine Metrik namens flow.engine.*

Ein älteres Dokument listete flow.engine.queue_depth · in_flight · dispatch_lag_ms · exec_p95_ms failed_per_min · script_timeout_per_min, aber Metriken mit solchen Namen existieren nicht. Die oben genannten fünf sind alles.

(flow.engine.enabled ist keine Metrik, sondern ein Konfigurationsschlüssel von engine.properties — das Master-Gate zum Abschalten der gesamten Flow-Engine.)

Muster zur Registrierung von metrikbasierten Alarmen​

4 Muster zur Überwachung eigener Flow-Metriken über erweiterte Alarme oder CEP → Trigger.

Muster A — Überschreitung der Fehlerquotenschwelle​

context EVERY_1_MINUTES
SELECT flow_id, count(CASE WHEN status='FAILURE' THEN 1 END) * 100.0 / count(*) AS err_pct
FROM AssetEvent.win:time(5 min)
WHERE event_type = 'FLOW_EXEC'
GROUP BY flow_id
HAVING err_pct > 5

Muster B — Auftreten von Backpressure in der Verarbeitungswarteschlange​

Alarm, wenn flow.engine.queue_depth > 500 länger als 1 Minute anhält — eine Situation, in der die Trigger-Auslösegeschwindigkeit die Verarbeitungsgeschwindigkeit überschreitet.

Muster C — Unterbrechung der Auslösung eines bestimmten Flows​

SELECT * FROM pattern [
every a = AssetEvent(event_type='FLOW_EXEC', flow_id='my-flow')
-> ( timer:interval(15 min)
and not AssetEvent(event_type='FLOW_EXEC', flow_id=a.flow_id) )
]

Alarm, wenn ein Flow, der normalerweise N-mal pro Minute auslöst, für mehr als 15 Minuten schweigt.

Muster D — Explosion der externen IO-Timeouts​

context EVERY_5_MINUTES
SELECT flow_id, node_id, count(*) AS timeout_count
FROM Log.win:time(5 min)
WHERE module = 'flow-engine' AND code = 'NODE_TIMEOUT'
GROUP BY flow_id, node_id
HAVING count(*) > 10

Empfehlung für Alarm-Ausgabekanäle​

AlarmartEmpfohlener Kanal
Fehlerquote·Auslöseunterbrechung (direkter Betrieb)E-Mail + Push-Benachrichtigung
Warteschlangen-Backpressure·Timeout-Explosion (System)Slack/Teams-Webhook
Automatische Diagnose (Referenz)Nur Diagnoseprotokoll

⚠️ Verlassen Sie sich für den Flow, der selbst für Alarme verwendet wird, niemals auf Metriken, die von diesem Alarm abhängen — wenn der Alarm-Flow abstürzt, kommt kein Alarm mehr. Überwachen Sie den Alarm-Flow über den externen Health-Check unter System → Monitoring.


Nachrichtenverarbeitungssemantik und Backpressure​

Garantieniveau und Backpressure-Verhalten der Flow-Engine bei der Nachrichtenverarbeitung.

Zustellgarantie — At-Least-Once​

Die Flow-Engine garantiert at-least-once-Zustellung.

FallVerhalten
Normale VerarbeitungEinmalige Auslösung → einmaliger Graphdurchlauf → einmaliger Abschluss
Neustart der Engine während der VerarbeitungIn der Trigger-Warteschlange verbliebene Nachrichten werden nach dem nächsten Boot erneut verarbeitet
Ausnahme auf Node-EbeneÜbergang nur in den FAILURE-Zweig. Die Nachricht verschwindet nicht
Timeout bei externer IOAutomatischer Retry über den FAILURE-Zweig + flow_retry möglich

Duplikationsmöglichkeit — Es handelt sich nicht um exactly-once. Wenn flow_create_* zwischendurch unterbrochen und erneut versucht wird, kann dieselbe ID zweimal eingehen; verwenden Sie daher on_duplicate=skip oder einen Idempotenz-Schlüssel des externen Systems.

Idempotenzschlüsselmuster​

Muster zur Sicherstellung der Idempotenz beim Aufruf externer Systeme aus dem Flow.

// flow_script_transform — 멱등성 키 생성
msg.data.idempotency_key =
msg.metadata.asset_id + '|' +
msg.metadata.ts + '|' +
msg.data.event_type;

Danach beim externen Aufruf im Header anhängen:

"headers": { "Idempotency-Key": "${data.idempotency_key}" }

Verarbeitungsreihenfolge — trigger-bezogenes FIFO​

Nachrichten desselben OriginatorsAnderer Originator
Trigger-bezogenes FIFO (in Ankunftsreihenfolge)Parallele Verarbeitung (unabhängig von der Reihenfolge)

Selbst wenn zwei Ereignisse der Anlage A fast gleichzeitig auftreten, werden die Ereignisse von A in der Auftrittsreihenfolge verarbeitet. Die Ereignisse von Anlage A und Anlage B können jedoch parallel von unterschiedlichen Workern verarbeitet werden.

Backpressure​

Verhalten, wenn die Verarbeitungsgeschwindigkeit der Auslösegeschwindigkeit nicht folgen kann.

SituationVerhalten
Warteschlangentiefe < 80 %Normal — neuer Trigger wird sofort eingereiht
Warteschlangentiefe 80–100 %Diagnose-WARN-Log tritt auf — Warteschlange nimmt weiterhin auf
Warteschlangentiefe = 100 % (voll)Neuer Trigger wird verworfen (drop) + Diagnose-ERROR-Log

Was der Operator tun sollte, wenn die Warteschlange voll ist​

  1. Unter System → Monitoring flow.engine.queue_depth prüfen
  2. Im Listenbildschirm den Flow identifizieren, dessen Ausführungsanzahl explodiert ist
  3. Den Vorabfilter des Triggers (*_pattern) dieses Flows einengen, um die Last zu senken
  4. Oder die Bereitstellung dieses Flows vorübergehend aufheben, um im Notfall zu handeln

Circuit Breaker (externe IO)​

Externe IO-Nodes (HTTP/Kafka/MQTT/E-Mail) werden für 30 Sekunden pauschal gesperrt, sobald folgende Bedingungen erfüllt sind.

BedingungSchwelle
Aufeinanderfolgende Fehlschläge innerhalb der letzten Minute≥ 10
Durchschnittliche Antwortzeit≥ 10 Sekunden

Während der Sperrung wird jede in diesen Node eingehende Nachricht sofort in FAILURE verzweigt. Erholt sich das externe System, wird die Sperrung automatisch aufgehoben. Dieses Verhalten isoliert einen externen Ausfall, sodass er nicht die gesamte Flow-Engine lähmt.

Der Zeitpunkt der Öffnung des Circuits wird im Diagnoselog als code = CIRCUIT_OPENED protokolliert. Hat sich das externe System schnell erholt, können Sie im metadata.retry_count der Ausführungshistorie fehlende Nachrichten manuell erneut ausführen.

Vermeidung von Zyklen (Schleifen)​

Wenn im Flow ein Zyklus wie der folgende entsteht, kann eine Endlosschleife auftreten.

A → B → C → A (잘못된 결선)

Die Flow-Engine blockiert Zyklen mit zwei Verteidigungslinien.

VerteidigungslinieVerhalten
max_depth=100Erzwungene Beendigung nach 100 durchlaufenen Nodes
max_revisit=3Nachricht wird beim 4. Besuch desselben Nodes verworfen + Diagnose-ERROR

Die Schleife SUCCESS-Zweig von flow_retry → zurück zum ursprünglichen Node ist ein beabsichtigter Zyklus, und da metadata.retry_count zusammen ansteigt, endet er normal, bevor max_revisit ausgelöst wird.


Was in der Ausführungshistorie zu sehen ist​

Der "Fehlercode-Katalog" aus dem älteren Dokument existierte nicht wirklich

Codes wie NODE_SCRIPT_TIMEOUT · FLOW_TIMEOUT · FLOW_MAX_DEPTH · TRIGGER_QUEUE_FULL WEBHOOK_AUTH_FAIL · DOMAIN_DUP_KEY waren in einer Tabelle aufgeführt, aber das Produkt erzeugt diese Strings nirgendwo. Eine Log-Suche nach diesem Code ergibt für immer 0 Treffer.

Was die Flow-Engine tatsächlich aufzeichnet, sind die folgenden 5 Ereignistypen.

Im Flow-Ausführungshistorie (mm_flow_log, linkes Menü Automation > Flow-Ausführungshistorie) werden fünf Ereignisarten geladen.

EreignistypWannLadebedingung
FLOW_STARTBeim Flow-EintrittImmer
FLOW_ENDEnde der Flow-Verarbeitung (Erfolg·Timeout gleichermaßen)Immer
NODE_INWenn der Node eine Nachricht empfängtNur im Debug-Modus
NODE_OUTWenn der Node eine Nachricht ausgibtNur im Debug-Modus
NODE_ERRORAusnahme während der Node-VerarbeitungImmer

Felder, die jede Zeile gemeinsam hat.

FeldInhalt
levelINFO / WARN / ERROR
flow_id · flow_node_id · node_name · node_typewelcher Flow, welcher Node
msg_idzur nachrichten-bezogenen Verfolgung — um den Ablauf einer Nachricht zu verfolgen, gruppieren Sie nach diesem Wert
message · error_messagefür Menschen lesbare Beschreibung, Ausnahmenachricht
duration_nsNode-Ausführungszeit (Nanosekunden) — nur bei NODE_OUT · NODE_ERROR aussagekräftig
Normalerweise werden keine Node-bezogenen Logs aufgezeichnet

NODE_IN · NODE_OUT werden nur im Debug-Modus geladen. Dass in der normalen Ausführungshistorie nur FLOW_START · FLOW_END sichtbar sind, ist normal. Um jeden Node nachzuvollziehen, aktivieren Sie den Debug-Modus des betreffenden Flows — dies erhöht jedoch die Log-Menge erheblich.

Nach Symptom suchen​

Statt nach Codes gehen Sie vom Symptom aus.

SymptomZuerst zu prüfen
Trigger löst aus, aber es scheint kein Node zu laufenIst der Flow bereitgestellt (Schalter ON) · filtert *_pattern des Triggers die Nachricht nicht heraus
Verarbeitung wird mittendrin unterbrochen30-Sekunden-Überschreitung (flow_timeout_ms) pro Nachricht. Prüfen Sie über die WARN-Warnung FlowExecutor timeout im Serverlog
Dieselbe Nachricht wird wiederholt verarbeitetZyklus. Wird automatisch durch max_revisit (3-mal) blockiert, prüfen Sie aber die Verdrahtung
Graph ist zu lang und endet nichtÜberschreitung von max_depth (100). In Subflows aufteilen
Node wirft eine Ausnahmeerror_message der NODE_ERROR-Zeile in der Ausführungshistorie prüfen
Externer Aufruf schlägt fehldata.response_status · data.error des betreffenden Nodes im Folgenode prüfen

Die Grenzwerte (100 · 3 · 30.000 ms) sind die Standardwerte von ExecutionState.


Cluster·Hochverfügbarkeit(HA)-Verhalten​

Bei einer Plattform-Installation in einer Clusterumgebung arbeitet die Flow-Engine verteilt nach folgenden Regeln.

Trennung der Node-Rollen​

RolleVerhalten
Leader (Leader)Einzelner Node, der Flow-Graph-Änderungen (Speichern/Bereitstellen/Aufheben) seriell verarbeitet
Worker (Worker)Allgemeiner Node, der Trigger-Auslösung·Nachrichtenverarbeitung parallel ausführt (alle Nodes fungieren auch als Worker)
Scheduler (Scheduler)Verantwortlich für die Auswertung des flow_schedule-Crons — derselbe Node wie der Leader

Der Leader-Node wird beim Plattform-Boot automatisch gewählt; fällt der Leader aus, wird automatisch einer der anderen Nodes zum Leader befördert. Der Operator muss ihn nicht selbst bestimmen.

Nachrichtenverteilung — Anlagen-bezogenes konsistentes Routing​

VerteilungsschlüsselVerhalten
originator.id (Anlage/Tag/Bestellungs-ID)Nachrichten derselben Anlage werden immer zum selben Worker geroutet — Sequenzgarantie
Externer Eingang (flow_on_webhook usw.)Round-Robin-Verteilung

Diese Regel verhindert, dass die Reihenfolge der Ereignisse der Anlage A durcheinandergerät, weil sie gleichzeitig von mehreren Workern verarbeitet werden. Im Ergebnis gilt anlagenbezogen Garantie der Verarbeitung durch einen einzelnen Worker, zwischen Anlagen parallele Verarbeitung gleichzeitig.

Verhalten bei Leader-Ausfall — Failover​

[Leader 다운 t=0]
↓
[다른 노드가 리더 승격 시도 t=0~3s]
↓
[새 리더 확정 t=3~5s] ← cron 스케줄·플로우 배포 변경 재개
↓
[기존 워커들은 정상 동작 유지 — 트리거 처리 영향 없음]
PhaseAuswirkung
0–3 SekundenCron-Auslösung flow_schedule vorübergehend pausiert / Trigger-Verarbeitung nicht betroffen
3–5 SekundenNeuer Leader bestätigt, Schedule wird wieder aufgenommen
Nach 5 SekundenNormal

Cron-Auslösungen führen nach der misfire-Richtlinie einmal versäumte Auslösungen sofort erneut aus. Bei laufendem Betrieb kann bei einer Auswertungseinheit von flow_schedule unter 5 Sekunden ein kurzfristiges Versäumnis sichtbar werden.

Persistenz der Trigger-Warteschlange​

ElementVerhalten
Position der Trigger-WarteschlangeIn-Memory-Warteschlange + permanenter Speicher (Transaktionsprotokoll)
Bei Node-NeustartUnverarbeitete, in der Warteschlange verbliebene Nachrichten werden nach dem nächsten Boot erneut dispatcht
Node-Ausfall während der VerarbeitungDiese Nachricht wird erneut verarbeitet, aber aufgrund der at-least-once-Garantie benötigt das externe System einen Idempotenzschlüssel

Checkliste für den Operator bei Cluster-Bereitstellung​

  1. Zeitsynchronisation aller Nodes (NTP) — Trigger-Auslösezeit muss zwischen den Nodes übereinstimmen
  2. Externe Systeme (MQTT-/Kafka-Broker) an einer Netzwerkposition platzieren, die alle Nodes erreichen können
  3. SMTP-Einstellungen des flow_send_email nur einmal in der Systemeinstellung registrieren — alle Nodes teilen sie sich
  4. Worker-Poolgröße (flow.engine.workers) je nach Anzahl der CPU-Kerne pro Node anpassen

Einzelknoten-Modus (Entwicklung·Kleinbetrieb)​

  • Leader·Worker·Scheduler laufen alle in einem einzigen Prozess
  • Kein Failover — fällt der Node aus, wird der Flow selbst gestoppt
  • Die Trigger-Warteschlange ist durch In-Memory + Disk gesichert und wird nach Neustart wiederherstellt

End-to-End-Trace​

Methode zur nachträglichen Verfolgung, wie eine Nachricht den gesamten Graphen durchlaufen hat.

Automatische Vergabe der Korrelations-ID​

Die Flow-Engine vergibt automatisch eine Korrelations-ID (correlation ID) an alle durch Trigger ausgelösten Nachrichten.

{
"type": "POST_TELEMETRY",
...,
"metadata": {
"trace_id": "tr-a1b2c3d4-e5f6-7890-...",
"span_id": "sp-01",
"parent_id": null,
...
}
}
FeldBedeutung
metadata.trace_idEine für den gesamten Trigger-Durchlauf eindeutige ID — alle den Graphen durchlaufenden Nachrichten teilen sie
metadata.span_idNode-spezifische eindeutige ID — wird bei jedem Node-Durchlauf aktualisiert
metadata.parent_idspan_id des unmittelbar vorherigen Nodes

Suche über trace_id im Ausführungshistorie-Bildschirm​

Wenn Sie im Ausführungshistorie-Bildschirm die ID in das Feld trace_id einfügen, werden die chronologischen Logs aller Nodes angezeigt, die diese Nachricht durchlaufen hat.

🔍 trace_id = tr-a1b2c3d4-...

[12:34:56.123] [trg] flow_on_tag_point 태그=MOTOR.TEMP, value=87
[12:34:56.125] [filter] flow_script_filter score>80 → TRUE
[12:34:56.126] [transform] flow_change_originator Tag → Asset
[12:34:56.130] [action] flow_create_work_order WO-20260513-001 생성
[12:34:56.241] [external] flow_send_email admin@... 발송 성공

Trace-Weiterleitung beim Subflow-Aufruf​

Wenn Sie mit dem Node flow_subflow einen anderen Flow aufrufen, wird dieselbe trace_id unverändert weitergeführt. Das heißt, alle Node-Logs des Haupt-Flows + des aufgerufenen Subflows sind über denselben Trace auffindbar.

Weiterleitung an externe Systeme​

Bei einem externen HTTP-Aufruf wird automatisch der X-Trace-Id-Header angehängt.

GET /api/orders HTTP/1.1
Host: erp.example.com
X-Trace-Id: tr-a1b2c3d4-e5f6-...
X-Span-Id: sp-04

Empfängt das externe System diesen Header und protokolliert ihn ebenfalls, können die Logs beider Systeme über dieselbe ID abgeglichen werden.

Anzeige der trace_id in Alarmen·E-Mails​

Wenn Sie im Alarmtext oder E-Mail-Template ${metadata.trace_id} einbeziehen, kann der Operator direkt nach Empfang des Alarms im Historienbildschirm den Vorfall sofort verfolgen.

제목: [긴급] 모터 과열 — ${metadata.asset_id}
본문:
시각: ${metadata.ts}
값: ${data.value}°C
trace: ${metadata.trace_id}
이력 보기: https://platform.example.com/flow/log?trace_id=${metadata.trace_id}

Aufbewahrungsdauer des Trace​

DatenAufbewahrungsdauer
trace_id und Node-bezogenes Span-Log7 Tage (gleich wie Ausführungshistorie)
Externe Speicherung (Langzeitaufbewahrung)Nutzung der externen Systemspiegelung unter Audit·Historien-Tracking

Wenn die trace_id zu lang ist und die Nachrichtengröße belastet, können Sie mit flow_script_transform eine Kurzform erzeugen, die nur die letzten 4 Zeichen (z. B. tr-...d4) anzeigt, und diese in Alarmen·E-Mails verwenden. Für die Suche wird jedoch die vollständige ID benötigt.


Katalog der Graph-Muster​

10 häufig verwendete Verdrahtungsmuster im Flow-Graphen.

Muster 1 — Pipeline (einfach seriell)​

[trigger] → [filter] → [transform] → [action]

| Merkmal | Nachricht durchläuft Nodes in Reihenfolge | | Anwendungsbeispiel | Schwellenwertüberschreitungsalarm → E-Mail-Versand |

Muster 2 — Fan-out (1 zu N)​

┌─→ [action 1]
[trigger] → [t] ─────┼─→ [action 2]
└─→ [action 3]

| Merkmal | Mehrere Aktionen verarbeiten eine Nachricht gleichzeitig | | Anwendungsbeispiel | Bei Alarmauftreten → E-Mail + SMS + Slack + Arbeitsauftragserstellung |

Kopien derselben Nachricht werden an mehrere Nodes verteilt. Jeder Zweig wird unabhängig verarbeitet, ein Fehlschlag eines Zweigs hat keine Auswirkung auf andere.

Muster 3 — Fan-in (N zu 1) — Merge​

[trigger A] ──┐
[trigger B] ──┼─→ [flow_merge] → [aggregator] → [action]
[trigger C] ──┘

| Merkmal | Nachrichten mehrerer Trigger innerhalb eines Zeitfensters gesammelt einmalig verarbeiten | | Anwendungsbeispiel | Alle innerhalb von 5 Minuten aufgetretenen Alarme zu einem Tagesbericht zusammenfassen |

Muster 4 — Scatter-Gather (verteilen → sammeln)​

[trigger] → [split] ─┬─→ [process] ──┐
├─→ [process] ──┼─→ [merge] → [action]
└─→ [process] ──┘

| Merkmal | Array elementweise aufteilen, verarbeiten und Ergebnisse wieder zusammenführen | | Anwendungsbeispiel | 100 externe Bestellungen parallel validieren und Ergebnisse gesammelt melden |

Muster 5 — Switch (Bedingungsverzweigung)​

┌─[CRITICAL]→ [긴급 알람]
[trigger] → [flow_switch] ──┼─[WARN] → [경고 알람]
└─[NORMAL] → [통과]

| Merkmal | Eine Nachricht je nach Bedingung auf unterschiedlichen Pfaden | | Anwendungsbeispiel | Trennung des Verarbeitungskanals nach Alarmpriorität |

Muster 6 — Retry with Fallback​

[risky] ─[FAILURE]─→ [flow_retry] ─[SUCCESS]─→ (다시 risky)
└[EXHAUSTED]→ [fallback action]

| Merkmal | Vorübergehende Störungen automatisch erneut versuchen, dauerhafte Störungen alternativ behandeln | | Anwendungsbeispiel | Bei externem API-Fehlschlag 3-maliger Retry, bei weiterhin fehlgeschlagen Benachrichtigung an Menschen |

Muster 7 — Circuit Breaker (Nutzung der Circuit-Sperrung)​

[trigger] → [throttle] → [external_io] ─[SUCCESS]─→ [save]
└[FAILURE]─→ [log only]

| Merkmal | Begrenzung der Aufrufgeschwindigkeit mit flow_throttle + pauschale Sperrung mittels Circuit Breaker | | Anwendungsbeispiel | Schutz vor Überlastung des externen Systems |

Muster 8 — Dead Letter Queue (DLQ)​

[main flow] ─[FAILURE]─→ [flow_save_attributes] → 별도 자산에 적재
↑
운영자가 주기적 점검 후 수동 재처리

| Merkmal | Dauerhaft fehlgeschlagene Nachrichten in separaten Speicher | | Anwendungsbeispiel | Sammlung fehlgeschlagener Nachrichten der externen ERP-Synchronisation (für manuelle Nachbearbeitung) |

Muster 9 — Sliding Window Aggregation​

[trigger] → [flow_throttle 60s] → [transform: 누적] → [action]
(마지막 60건만 유지)

| Merkmal | Entscheidungsfindung anhand des Zustands innerhalb eines Fensters der letzten N Einträge | | Anwendungsbeispiel | Bei über 30 Alarmen in den letzten 5 Minuten Standort in den Notfallmodus versetzen |

Muster 10 — Saga (mehrstufige Transaktion)​

[start] → [step1] ─OK→ [step2] ─OK→ [step3] ─OK→ [complete]
│ │ │
└─FAIL→[rollback1] │
│ │
┌─FAIL→[rollback1+2]
│
└─FAIL→[rollback1+2+3]

| Merkmal | Teilfehlschläge von Vorgängen über mehrere externe Systeme durch Kompensation behandeln | | Anwendungsbeispiel | Erstellung eines Arbeitsauftrags → Anlagenreservierung → ERP-Synchronisation → Benachrichtigung des Mitarbeiters (bei Fehlschlag einer Stufe werden alle vorherigen Stufen rückgängig gemacht) |

Leitfaden zur Musterauswahl​

AnforderungEmpfohlenes Muster
Einfacher SchwellenwertalarmPipeline (1)
Ein Ereignis → mehrere KanäleFan-out (2)
Mehrere Ereignisse → eine ZusammenfassungFan-in / Merge (3)
Massenverarbeitung von ArraysScatter-Gather (4)
VerzweigungsverarbeitungSwitch (5)
Zuverlässigkeit externer APIRetry (6)
Schutz externer SystemeCircuit (7)
Aufbewahrung fehlgeschlagener NachrichtenDLQ (8)
Entscheidungsfindung anhand kumulierter letzter N EinträgeSliding (9)
Konsistenz über mehrere externe SystemeSaga (10)

Best Practices für Flow-Tests​

Teststrategie zur sicheren Änderung·Bereitstellung von Flows.

3-stufiger Test — Einheit → Integration → Simulation​

StufeWerkzeugPrüfgegenstand
① EinheitBearbeitungsbildschirm ▶ TestlaufEigenständiges Verhalten eines einzelnen Nodes (Skriptausdruck, Antwort externer Aufrufe)
② Integrationderselbe Bildschirm, temporäre Payload + Live-Debug ONGesamtsequenz·Verzweigung des Graphen
③ SimulationBereitstellung + Warten auf realen Trigger (Staging-Umgebung)Realer Nachrichtenfluss·Verbindung mit externen Systemen

Bibliothek von Testlauf-Payloads​

Trigger-spezifische Payload-Beispiele, die Sie in den Testlauf-Dialog einfügen können, finden Sie im Abschnitt Payload-Beispiele nach Trigger. Erstellen Sie auch vorab Grenzfälle, die im Betrieb häufig vorkommen.

Beispiele für Grenzfälle​

FallPayload
null-Feld{"value": null} — ob das Skript null-sicher ist
Leerer String{"value": ""} — Prüfung, ob ein leerer String als 0 interpretiert wird
Negativ{"value": -1} — ob die Schwellenwertprüfung ±-Vorzeichen wie beabsichtigt behandelt
Riesige Zahl{"value": 1e20} — Überlauf/Genauigkeit
Unicode{"name": "한글-Émoji-🚀"} — Kodierung des externen Systems

Sicheres Änderungsverfahren​

1. 기존 플로우를 [내보내기] (JSON 파일 저장)
2. 새 플로우를 사본으로 만듦 (이름 끝에 `_v2`)
3. 사본의 트리거 패턴을 좁혀 일부 자산만 매칭 (예: TEST-* 사이트만)
4. 신구 동시 배포 — 새 버전 데이터 확인
5. 1주일 안정성 검증 후 신 버전을 전체 트리거 패턴으로 변경
6. 구 버전 해제 + 보관

Aufbewahrung von Regressionstestszenarien​

Es wird empfohlen, häufig verwendete Szenarien als Textdatei aufzubewahren und nach jeder Änderung erneut auszuführen.

# regression-tests/alarm-to-workorder.json
{
"case": "고온 알람 → 워크오더 자동 생성",
"input": {
"type": "TAG_ALARM",
"data": { "alarm_band": "HI_HI", "value": 95.0 }, ...
},
"expected": {
"domain_changes": ["WorkOrder.CREATED"],
"notifications": ["email:admin@example.com"]
}
}

Muster für die Simulation (Mock) externer Systeme​

Um in der Staging-Umgebung Antworten externer Systeme zu simulieren:

MethodeBeschreibung
url von flow_http_request auf Mock-ServerProduktions-URL von der Staging-URL-Variable getrennt
Datasource von flow_jdbc_poll ändernNur von Produktions-DB auf Staging-DB ändern
to_field von flow_send_email auf fake@example.comVermeidung versehentlichen Versands

Lasttest nach Zählerreset​

  1. Zählerreset (alles) der neuen Flow-Version
  2. 5 Minuten normale Trigger-Auslösung durchführen
  3. Verarbeitungs-/Fehlerzähler, durchschnittliche Verarbeitungszeit im Listenbildschirm prüfen
  4. Steigt die p95-Verarbeitungszeit gegenüber dem bisherigen Wert um mehr als 20 %, Ursachenanalyse und Rollback-Prüfung durchführen

Leistungsgrenzen und Tuning​

Verarbeitungsgrenzen und Tuning-Tipps der Flow-Engine.

Standardgrenzen​

ElementStandardwertAnmerkung
Anzahl der Node-Besuche pro Nachricht (max_depth)100Erzwungene Beendigung, wenn nach 100 durchlaufenen Nodes nicht beendet
Anzahl der Wiederbesuche desselben Nodes (max_revisit)3Vermeidung von Zyklus-Endlosschleifen
Flow-Verarbeitungszeit (flow_timeout_ms)30.000 msErzwungene Beendigung bei Überschreiten von 30 Sekunden pro Nachricht
Timeout externer IO-Nodes5.000 ms (timeout_ms)HTTP/Kafka/MQTT usw.
Skript-Ausführungstimeout500 ms (timeout_ms)pro Node
Aufbewahrung der Ausführungshistorie7 Tagedanach automatisch abgelaufen

Empfohlene, häufig verwendete Fenstergrößen​

NodeEmpfohlenes FensterAnmerkung
flow_throttle1.000–60.000 msAn das Limit der externen System-API anpassen
flow_debounce500–5.000 msNur bei Wunsch, ausschließlich stabile Werte durchzulassen
flow_merge5.000–60.000 msZu kurz führt zu Fragmentierung, zu lang erhöht die Latenz
flow_retry-BackoffStart 1.000 ms × 2-fachBei 5 Versuchen 1·2·4·8·16 Sekunden

Möglichkeiten zur Erhöhung des Durchsatzes​

  • Trigger-Vorabfilter — mit *_pattern nur benötigte Nachrichten einlassen (am wirksamsten)
  • Vereinfachung des Graphen durch Subflow — Hauptgraph nur für Verzweigung·Routing, schwere Verarbeitung in Subflow
  • Externe IO asynchron verdrahten — Externe API-Last mit flow_delay / flow_throttle glätten
  • Debug-Modus nur während der Verifizierungsphase — nach Betriebsstabilisierung Debug-Modus AUS
  • Nur benötigte Kategorien verdrahten — schwere Nodes wie Edge·externe Anbindung nicht unbedingt in jeder Verzweigung verdrahten

Nachrichtengröße​

data / metadata der Nachricht werden JSON-serialisiert und in der Ausführungshistorie geladen. Extrahieren Sie bei riesigen Payloads (mehrere MB Response-Body usw.) möglichst mit einem Transformationsnode nur die benötigten Schlüssel. Sowohl bei der Aufbewahrung der Historie, der Debug-Anzeige als auch beim Subflow-Aufruf ist der Verarbeitungsaufwand proportional zur Nachrichtengröße.


Audit·Historien-Tracking​

Orte, die Sie zur Verfolgung der Änderungs-/Ausführungshistorie eines Flows prüfen sollten.

Historie der Graph-Änderungen​

  • Automatischer Snapshot — wird bei jedem Graph-Speichern versionsweise geladen. Um auf einen vorherigen Zustand zurückzusetzen, wenden Sie sich an den Administrator.
  • Änderer/Änderungszeitpunkt — die Spalte Letzte Änderung im Listenbildschirm zeigt den jüngsten Speicherzeitpunkt. Der Änderer wird auf Basis des systemauthentifizierten Benutzers erfasst.
  • Empfohlene Erfassung des Änderungsgrunds — im Feld Beschreibung der Flow-Metadaten gemeinsam Änderungsgrund·Verantwortlichen·zugehörige Ticketnummer zu erfassen, erhöht die Nachvollziehbarkeit.

Verfolgung von Ausführungsereignissen​

  • Verfolgung per Nachrichten-ID — mit dem Filter Nachrichten-ID im Ausführungshistorie-Bildschirm können Sie den gesamten Ablauf (FLOW_START → alle NODE_IN/NODE_OUT → FLOW_END) einer einzelnen Nachricht chronologisch abrufen.
  • CSV-Export — mit der Schaltfläche CSV herunterladen im Ausführungshistorie-Bildschirm können Sie das aktuelle Abfrageergebnis exportieren und an ein externes Audit-System weiterleiten.

Historie der Domänenänderungen​

Domänenänderungen, die von den Aktionsnodes (flow_create_* / flow_update_* / flow_delete_*) des Flows durchgeführt werden, werden alle an denselben Domänenservice delegiert und daher auch in der domänenbezogenen Änderungshistorie des Backoffice-Bildschirms erfasst. Die Bearbeiter-ID wird beispielsweise als insert_user_id="flow" gekennzeichnet, um sie von Änderungen durch normale Benutzer zu unterscheiden.

Langzeitaufbewahrung durch externe Speicherung​

Falls eine Langzeitaufbewahrung über die Aufbewahrungsdauer der Ausführungshistorie (7 Tage) hinaus benötigt wird, erstellen Sie einen separaten Flow, um Kernereignisse in ein externes System (Kafka·externe DB usw.) zu laden.

[flow_on_tag_alarm]
│
▼
[flow_kafka_publish: topic=audit.alarm.events]

Checkliste für die Bereitstellung neuer Flows​

Zu prüfende Punkte vor der Bereitstellung eines neuen Flows in der Produktionsumgebung.

Graphstruktur

  • Ist genau ein Trigger-Node (oder bewusst mehrere) verdrahtet
  • Ist der FAILURE-Ausgang aller Aktionsnodes behandelt (mindestens flow_log)
  • Falls ein Zyklus vorliegt, ist er beabsichtigt verdrahtet (z. B. flow_retry) und befindet er sich innerhalb des Schutzes max_revisit
  • Sind retry_count/retry_delay_ms oder flow_retry bei externen IO-Nodes verdrahtet

Node-Konfiguration

  • Ist der *_pattern des Triggers nicht zu eng oder zu weit
  • Existiert der Pfad der dynamischen Option *_field tatsächlich in der Nachricht
  • Sind alle NOT-NULL-Felder des Create-Nodes befüllt (außer automatischer Ergänzung)
  • Ist die Teilaktualisierung beim Update-Node tatsächlich beabsichtigt

Verifizierung·Test

  • Mit normaler Payload einmal SUCCESS-Zweig durchlaufen
  • Mit abnormaler Payload (fehlendes Pflichtfeld usw.) FAILURE-Zweig durchlaufen
  • Mit externem IO-Fehlschlagfall Retry → EXHAUSTED-Zweig durchlaufen (falls zutreffend)
  • Stimmt die INFO/ERROR-Anzeige im Live-Debug-Panel mit der Absicht überein
  • Werden alle Schritte im Bildschirm /flow/log aufgezeichnet

Betriebssicherheit

  • Ist ein Backup (Graph-JSON-Export) extern aufbewahrt
  • Sind Änderungsgrund·Verantwortlicher in der Flow-Beschreibung erfasst
  • Wurden Empfänger bei vorhandener Benachrichtigungsverdrahtung (Email/SMS/Push) verifiziert
  • Gibt es einen Plan zur Überwachung der Ausführungshistorie für 5–10 Minuten unmittelbar nach der Bereitstellung

Bereitstellungsstrategie — Canary / Blue-Green / A·B-Test​

3 Strategien zur sicheren Einführung eines neuen Flows. Alle Strategien lassen sich ausschließlich mit den Basisfunktionen der Plattform (Trigger-Muster·Nachrichten-Dispatch·Live-Debug) implementieren.

Strategie 1 — Canary (schrittweise Anwendung nur auf einige Anlagen)​

Wenden Sie den neuen Flow zunächst nur auf einige Anlagen an, beobachten Sie eine Zeit lang und weiten Sie ihn dann auf alle aus.

[1단계 출시]
새 플로우 v2 — 트리거 패턴: asset_id LIKE 'LINE-1.%' (1개 라인만)
기존 플로우 v1 — 트리거 패턴: asset_id LIKE 'LINE-2.%' OR 'LINE-3.%' OR ...

[2단계 확대 (1주일 후 안정 확인)]
v2 패턴: 'LINE-1.%' OR 'LINE-2.%'
v1 패턴: 'LINE-3.%' OR 'LINE-4.%'

[3단계 전체 (2주 후)]
v2 패턴: '%' ← 모든 자산
v1 해제·보관

Checkliste für den Canary-Fortschritt​

ZeitraumÜberwachungspunkte
Tag 1Fehlerquote < 1 % / durchschnittliche Verarbeitungszeit innerhalb ±20 % gegenüber bisher
1 WocheExterne Systemanbindung 100 % normal / angemessene Alarmauftrittsfrequenz
2 WochenKumulierte Statistik / Nutzerfeedback / Entscheidung über Ausweitung auf die nächste Linie

Wählen Sie für die Canary-Linie eine Linie mit geringer Auswirkung selbst unter den laufenden Linien (z. B. Linien mit häufiger Wartung oder nur nächtlichem Betrieb).

Strategie 2 — Blue-Green (gleichzeitiger Betrieb alt·neu mit sofortigem Umschalten)​

[Blue (현재)] [Green (새 버전)]
플로우 v1 — 배포됨 플로우 v2 — 배포 + 격리된 originator
모든 트리거 처리 metadata.test_mode=true 인 메시지만 처리

[전환 결정 시점]
v2 트리거 패턴을 v1 과 동일하게 변경 (1초)
v1 해제 토글 (1초)

Der Kern von Blue-Green ist der sofortige Wechsel bei gleichzeitiger Bereitstellung beider Versionen — bei Problemen wird v1 sofort wieder bereitgestellt, um zurückzurollen.

Isolierte Verdrahtung von v2​

[trigger 모든 메시지]
↓
[flow_script_filter — metadata.test_mode === true]
↓ TRUE
[새 로직]

Testnachrichten werden über die API /flow/{id}/run mit explizitem metadata.test_mode=true gesendet.

Strategie 3 — A/B-Test (Leistungs-/Ergebnisvergleich)​

Zwei Versionen empfangen dieselbe Nachricht und führen jeweils unterschiedliche Aktionen aus, deren Ergebnisse verglichen werden.

[trigger 메시지]
↓
[flow_split (메시지 복제)]
├ A 경로 → 기존 v1 액션 → [flow_save_attributes target=stats_v1]
└ B 경로 → 새 v2 액션 → [flow_save_attributes target=stats_v2]

Anschließend im Tagesstatistik-Bildschirm stats_v1 vs stats_v2 die kumulierten Ergebnisse vergleichen.

Automatische Analyse des A/B-Vergleichs​

-- EQL 으로 두 버전 비교 (예: 알람 생성 누적)
context EVERY_1_HOURS
SELECT
count(CASE WHEN metadata.flow_version='v1' THEN 1 END) AS v1_count,
count(CASE WHEN metadata.flow_version='v2' THEN 1 END) AS v2_count
FROM AssetAlarm.win:time(1 hour)

Leitfaden zur Strategieauswahl​

SituationEmpfohlene Strategie
Erste Einführung eines neuen AutomatisierungsszenariosCanary — auf einer Linie verifizieren, dann ausweiten
Große Änderung an bestehender Logik (Strukturumbau)Blue-Green — sofortiges Rollback möglich
Messen, welcher von zwei Algorithmen besser istA/B-Test
Einfache Anpassung eines OptionswertsDirekte Änderung — nach metadata.audit_diff-Notiz 1 Woche überwachen

Rollback-Verfahren (gemeinsam)​

Bei Problemauftreten sofort zurückrollen:

  1. Im Listenbildschirm die neue Version über den Aufheben-Schalter deaktivieren
  2. (Bei Canary/A·B) das Trigger-Muster auf 0 Übereinstimmungen ändern
  3. 5 Minuten überwachen, ob die bestehende Version allein normal funktioniert
  4. Diagnoseprotokoll auf code=FLOW_NOT_DEPLOYED prüfen
  5. Ursachenanalyse — im Ausführungshistorie fehlgeschlagene Nachrichten über trace_id verfolgen

Vor-Release-Checkliste (Kurzfassung)​

Das Wesentliche der Checkliste für die Bereitstellung neuer Flows auf einer Ansicht:

[ ] 테스트 실행으로 정상·경계·실패 시나리오 모두 통과
[ ] 외부 IO 노드에 timeout_ms / 재시도 정책 설정됨
[ ] 자격 증명은 ${creds.*} 참조 (평문 미포함)
[ ] 트리거 패턴이 의도한 자산만 매칭
[ ] 영향받는 도메인 (자산/태그/주문) 식별됨
[ ] 운영 시간(특히 야간) 영향 검토됨
[ ] 롤백 시점·기준·담당자 결정됨
[ ] [감사 로그](#audithistorien-tracking) 에 변경 의도 메모 작성됨

Schnelle Node-Konfigurationsreferenz​

Cheat-Sheet mit den wichtigsten Konfigurationen häufig verwendeter Nodes im Betrieb.

Trigger-Schnellkonfiguration​

NodeKernoption
flow_schedulecron (z. B. 0 */5 * * * ? = alle 5 Minuten), oder interval_ms
flow_on_webhookkeine Option — Auslösung von außen über POST /webhook/flow/{flow_id}
flow_on_mqtt_subscribebroker_url, topic, client_id, username/password
flow_jdbc_polldsn, sql, interval_ms
flow_on_* (Domain)*_pattern (Glob — z. B. MOTOR-*, SITE-?)

Transformation-Schnellkonfiguration​

NodeKernoption
flow_script_transformlanguage (JS/EQL), script, timeout_ms (Standard 500)
flow_change_originatorentity_type, id_field
flow_rename_keysmapping (z. B. {"old":"new"})
flow_templatetemplate (${data.x} / ${metadata.y} Substitution)
flow_splitpath (Array-Position, Standard data)
flow_to_emailsubject_template, body_template

Ablaufsteuerung-Schnellkonfiguration​

NodeKernoption
flow_delaydelay_ms
flow_throttlemax_msgs, window_ms, (Verzweigung: SUCCESS/THROTTLED)
flow_debouncewindow_ms
flow_mergewindow_ms (kumuliert im Array data.merged)
flow_subflowtarget_flow_id
flow_retrymax_attempts (Standard 3), backoff_ms (Standard 1000), backoff_multiplier (Standard 2.0)
flow_loglevel (INFO/WARN/ERROR), prefix
flow_noop(keine Option)

Externe Anbindung-Schnellkonfiguration​

NodeStatische OptionDynamische Option (*_field)
flow_http_requestmethod, url, headers, body_template, timeout_ms, retry_count, retry_delay_msurl_field, method_field, body_field
flow_kafka_publishbootstrap_servers, topic, value_template, headerstopic_field, key_field
flow_mqtt_publishbroker_url, topic, qostopic_field
flow_webhook_callbackurl, method, headersurl_field
flow_send_emailto, cc, subject, bodyto_field, cc_field, subject_field, body_field
flow_send_smsto, textto_field, text_field
flow_send_pushtitle, bodytitle_field, body_field
flow_jdbc_querydsn, sql, params_field—

Aktion — Integration/Speicherung-Schnellkonfiguration​

NodeKernoption
flow_save_tag_pointtag_id_field (Standard metadata.tag_id), value_field, timestamp_field
flow_save_attributesentity_type_field, id_field, attributes_field
flow_dds_publishtype, originator_field, payload_field
flow_publish_asset_eventasset_id_field, event_type_field, severity_field, details_field
flow_publish_asset_commandasset_id_field, tag_id, cmd_key_field, payload_field

Domain-CRUD-Schnellkonfiguration​

NodeKernoption
flow_create_*domänenspezifische Felder + dynamische Option *_field. NOT-NULL-Felder teilweise automatisch ergänzt (siehe Tabelle Domain CRUD zu den automatisch ergänzten Feldern)
flow_update_*Teilaktualisierung: nur eingegebene Felder werden aktualisiert, leere Werte werden ignoriert. Vollständiges Überschreiben mit Delete + Create Kombination
flow_delete_**_id_field
flow_start/end/pause/resume_work_orderorder_id_field (Standard data.order_id)
flow_abort_work_order+ abort_code_field, abort_notes_field
flow_update_tag_alarm_band_numerictag_id_field, hi_field usw. (nur Eingabefelder werden aktualisiert)

Edge-Schnellkonfiguration​

Alle Edge-Nodes verwenden dieselben Optionen.

OptionBeschreibung
urlEdge-REST-Endpunkt (z. B. http://edge.local:60000/opc/server)
methodHTTP-Methode (bei fehlender Angabe Node-spezifischer Standardwert)
headersJSON-Header (Authentifizierungstoken usw.)
body_templateRequest-Body (bei fehlender Angabe wird data unverändert gesendet)
timeout_ms5000

Flow REST API — Flow programmatisch steuern​

REST-API zur Verwaltung von Flows als Code über externe Automatisierungstools (Ansible/GitOps/CI-Pipeline), oder wenn ein externes System einen Flow sofort ausführen soll.

Authentifizierung​

Alle API-Aufrufe werden mit einem Token authentifiziert, das unter Sicherheit → API-Authentifizierungstoken ausgestellt wurde, als Header angehängt.

Authorization: Bearer {api_token}

Liste der Endpunkte​

1) Flow-Liste abrufen​

GET /flow/list
curl -H "Authorization: Bearer ${TOKEN}" \
https://platform.example.com/flow/list

Antwort:

{
"data": [
{ "flow_id": "flow-abc123", "flow_name": "MES 동기화", "deployed": true,
"node_count": 12, "exec_count": 9430, "error_count": 2, "last_exec_at": 1746247200000 },
...
]
}

2) Einzelnen Flow abrufen​

GET /flow/get/{flow_id}

Der Response-Body enthält alle Graph-Nodes·Relationen·Optionen. Direkt für Backup/Versionsverwaltung verwendbar.

3) Flow erstellen​

POST /flow/create
Content-Type: application/json

{
"flow_name": "신규 자동화",
"description": "외부 알림 → 워크오더 자동 생성",
"deployed": false
}

Verwenden Sie die aus der Antwort empfangene flow_id für nachfolgende Aufrufe.

4) Flow bearbeiten (Metadaten)​

POST /flow/update
Content-Type: application/json

{
"flow_id": "flow-abc123",
"flow_name": "수정된 이름",
"description": "..."
}

5) Graph speichern (Massenersetzung von Node·Relation)​

POST /flow/{flow_id}/graph
Content-Type: application/json

{
"nodes": [ { "node_id": "n1", "type": "flow_on_tag_point", "options": {...}, "x": 100, "y": 100 }, ... ],
"relations": [ { "from_node_id": "n1", "to_node_id": "n2", "relation": "TRUE" }, ... ]
}

Das Speichern des Graphen ist eine Transaktion — bei Validierungsfehlern wird der gesamte Graph zurückgerollt.

6) Bereitstellen / Aufheben​

Wenn Sie das Feld deployed der Flow-Metadaten ändern, wird automatisch bereitgestellt·aufgehoben.

# 배포
curl -X POST -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" \
-d '{"flow_id":"flow-abc123","deployed":true}' \
https://platform.example.com/flow/update

7) Sofortige Ausführung (manueller Trigger)​

POST /flow/{flow_id}/run
Content-Type: application/json

{
"type": "WEBHOOK",
"originator": { "entity_type": "External", "id": "manual-run" },
"data": { "test": true }
}

Wird sofort ab dem ersten Node ausgeführt, ohne den Vorabfilter des Trigger-Nodes zu durchlaufen. Nützlich für manuelle Verifizierung·Debugging.

8) Dispatch (Auslösung unter Umgehung des Triggers)​

POST /flow/dispatch
Content-Type: application/json

{
"type": "POST_TELEMETRY",
"originator": { "entity_type": "Tag", "id": "MOTOR-001.SPEED" },
"data": { "value": 1500 },
"metadata": { "tag_id": "MOTOR-001.SPEED", "ts": 1746247200000 }
}

Die Nachricht wird über den normalen Trigger-Verarbeitungspfad eingespeist — alle Flows, die auf diese Nachricht passen, werden gleichzeitig ausgelöst.

9) Statistik zurücksetzen​

POST /flow/{flow_id}/stats/reset-errors — 에러 카운트만 초기화
POST /flow/{flow_id}/stats/reset-all — 전체 카운트 초기화

10) Export / Import — Graph-Backup​

# Export — JSON 파일로 다운로드
curl -H "Authorization: Bearer ${TOKEN}" \
https://platform.example.com/flow/${FLOW_ID}/export \
-o flow-backup.json

# Import — 같은 JSON 을 다른 환경에 등록
curl -X POST -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" \
--data @flow-backup.json \
https://platform.example.com/flow/import

Bei Import mit kollidierender ID wird automatisch eine neue ID ausgestellt. Externe Abhängigkeiten (Anmeldedaten·Anlagen-ID usw.) müssen nach dem Import separat zugeordnet werden.

11) Alle Flows neu bereitstellen​

POST /flow/redeploy

Wird nach großflächigen Änderungen oder nach Node-Neustart zur Massensynchronisation verwendet. Gehen Sie mit Aufrufen im Betrieb vorsichtig um — es kann zu vorübergehenden Verarbeitungsverzögerungen kommen.

12) Selbstdiagnose​

POST /flow/selftest

Prüft einmal die internen Komponenten der Flow-Engine (Trigger-Warteschlange·Dispatcher·Node-Registry·Skript-Laufzeit) und gibt den Status zurück. Das Ergebnis wird auch im Diagnoseprotokoll erfasst.

13) Node-Katalog abrufen​

GET /flow/catalog

Gibt alle aktuell registrierten Node-Typen·Optionsschemata zurück. Wird von der UI zur dynamischen Erstellung des Inspektors verwendet. Auch als Referenz für externe Tools bei der automatischen Graph-Erstellung.

Auslösung von außen über Webhook-Trigger​

Flows, die den flow_on_webhook-Trigger enthalten, können über folgende URL direkt von einem externen System ausgelöst werden.

POST /webhook/flow/{flow_id}
Authorization: Bearer {token} 또는 X-API-Key: {token}
Content-Type: application/json

{
"order_no": "PO-001",
"customer": "ACME",
"quantity": 1000
}

Antwort:

{ "status": "ACCEPTED", "trace_id": "tr-..." }
AntwortcodeBedeutung
200In Nachrichtenwarteschlange eingereiht (tatsächliches Verarbeitungsergebnis asynchron)
401Authentifizierungstoken falsch/fehlend
404Flow-ID nicht vorhanden oder nicht bereitgestellt
413Body überschreitet 256 KB
422Trigger-Node ist nicht flow_on_webhook
429Aufrufbegrenzung pro Minute überschritten

Beispiele für die Anbindung externer Automatisierungstools​

GitHub Actions — Flow-Bereitstellung bei PR-Merge​

- name: 플로우 배포
run: |
curl -X POST \
-H "Authorization: Bearer ${{ secrets.PP_TOKEN }}" \
-H "Content-Type: application/json" \
--data @flows/mes-sync.json \
https://platform.example.com/flow/import

Ansible — Batch-Verwaltung von Flows​

- name: 모든 플로우 백업
uri:
url: "https://platform.example.com/flow/{{ item }}/export"
headers:
Authorization: "Bearer {{ pp_token }}"
dest: "/backups/{{ item }}.json"
loop: "{{ pp_flow_ids }}"

Jenkins — Selftest bei jedem neuen Build​

stage('PlantPulse Flow Selftest') {
steps {
sh """
curl -X POST -H 'Authorization: Bearer ${PP_TOKEN}' \\
https://platform.example.com/flow/selftest \\
--fail-with-body
"""
}
}

API Rate Limit​

EndpunktLimit pro Minute (pro Token)
GET /flow/list · get · catalog600
POST /flow/create · update · delete60
POST /flow/{id}/run · dispatch · webhook/{id}1.000
POST /flow/redeploy · selftest10

Bei Überschreitung des Limits Antwort 429 Too Many Requests.


OPC/PLC-Industrieintegrationsmuster​

Sammlung von industriespezifischen Integrationsszenarien. Kombinierte Nutzung der 22 Edge-Nodes und der 4 Nodes zur Anlagen-Ereignis-Veröffentlichung.

Muster A — Automatische OPC-Server-Registrierung​

Beim Anlauf einer neuen Linie automatische Registrierung eines OPC-Servers am Edge mit von ERP empfangenen Linieninformationen.

[flow_on_webhook]
↓ (data = {"line_id":"LINE-7","host":"10.0.7.10","port":4840})
[flow_change_originator]
↓ (originator → Edge:EDGE-A)
[flow_edge_opc_create]
↓ (path=/api/v1/opc, body={"opc_id":"OPC-${data.line_id}","host":"${data.host}","port":${data.port}})
[flow_edge_opc_start]
↓ (수집 시작 명령)
[flow_save_attributes]
↓ (등록 이력을 자산 메타에 기록)

Der Edge-Node führt automatisch ein Lookup von api_key in der Master-Tabelle mm_edge durch. Der Operator muss keine separate Authentifizierungskonfiguration vornehmen.

Muster B — Automatische Ausgabe von PLC-Befehlen​

Bei Auftreten eines Anlagenalarms wird automatisch ein Stoppbefehl an die PLC ausgegeben.

[flow_on_asset_alarm]
↓ where priority='ERROR' AND alarm_band='TRIP_HI'
[flow_publish_asset_command]
↓ (event_type='STOP', payload={"reason":"trip_high","triggered_by":"flow"})
[flow_log] (감사 로그)

flow_publish_asset_command wird sofort an das Befehlstopic der Anlage (asset/{id}/cmd/STOP) übermittelt, und der Edge führt den OPC-Write an die PLC aus.

Muster C — Massenregistrierung von OPC-Tags (CSV/Excel-Eingang)​

Bei der Einrichtung neuer Anlagen werden 100–1000 Tags aus einer CSV auf einmal registriert.

[flow_jdbc_poll] ← 외부 DB 에 적재된 CSV 행
↓ (한 행 = 한 메시지)
[flow_script_transform] ← 태그 정의 가공
↓
[flow_create_tag] ← 도메인 등록 (NOT NULL 자동 보강)
↓
[flow_edge_tag_create] ← 엣지에 동기화
↓
[flow_log] (성공 카운트)

Bei Registrierung von 1.000 Tags wird empfohlen, mit flow_throttle auf höchstens 100 pro Minute zu glätten. Der Edge kann vorübergehend langsamer antworten.

Muster D — Automatische Wiederherstellung bei OPC-Verbindungsabbruch​

Automatischer Neustart, wenn die OPC-Verbindung abgebrochen war und sich wieder erholt.

[flow_on_opc_status]
↓ where prev_status='CONNECTED' AND status='DISCONNECTED'
[flow_delay 30s] ← 잠시 안정화 대기
↓
[flow_edge_opc_start] ← 수집 재시작 시도
↓ SUCCESS: 정상
└ FAILURE: [flow_retry max=3] → EXHAUSTED: [관리자 알림]

Muster E — Linienstatusprüfung bei Schichtbeginn​

Prüft alle Linien eines Standorts zu Beginn jeder Schicht.

[flow_schedule cron='0 0 7,15,23 * * ?'] ← 7시·15시·23시
↓
[flow_edge_monitoring] ← 엣지에서 OPC 상태 전체 조회
↓ data.opcs = [...]
[flow_split] ← 배열을 행별 메시지로
↓
[flow_script_filter] ← status != 'CONNECTED' 만
↓
[flow_send_email] ← 비정상 OPC 만 한 통의 메일에 합쳐 발송

Muster F — Automatische Mitarbeiterzuordnung bei Schichtwechsel​

Automatische Zuordnung des Mitarbeiters zum Arbeitsauftrag entsprechend der Änderung des Dienstplans.

[flow_on_entity_event type='ENTITY_UPDATED' Calendar]
↓
[flow_script_filter (시프트 시작 시각이 지금인 경우만)]
↓
[flow_jdbc_query (그 시프트의 작업자 목록 조회)]
↓ data.employees=[...]
[flow_split]
↓
[flow_update_work_order (작업자 매핑)]

Muster G — Gleichzeitiger Aufruf mehrerer PLCs (Scatter-Gather)​

Gleichzeitiger Aufruf von Daten mehrerer PLCs und anschließende Konsolidierung der Ergebnisse.

[flow_on_webhook]
↓ data.targets=['PLC-1','PLC-2','PLC-3']
[flow_split]
↓ (3개로 분할)
[flow_edge_tag_read]
↓ (병렬 호출)
[flow_merge window=5s]
↓ data.merged=[...]
[flow_script_transform (data.summary 만들기)]
↓
[flow_publish_asset_aggregation]

Muster H — Automatische Anpassung des Alarmbands​

Automatische Anwendung der aus der Vorhersageanalyse gelernten LIMIT_MIN/MAX-Werte auf das Alarmband.

[flow_schedule cron='0 0 4 * * MON'] ← 매주 월요일 4시
↓
[flow_jdbc_query (forecast 결과 조회)]
↓ data.tags=[{tag_id, limit_min, limit_max}]
[flow_split]
↓
[flow_update_tag_alarm_band_numeric] ← lo=limit_min, hi=limit_max
↓ SUCCESS
[flow_log] (적용 결과 기록)

Muster I — Automatische Klassifizierung von Downtime​

Klassifizierung von Anlagenstoppereignissen nach Ursache, um sie präzise in der OEE-Verfügbarkeit zu berücksichtigen.

[flow_on_asset_event event_type='SHUTDOWN']
↓
[flow_switch]
├ CASE 점심: hour_of_day(ts) BETWEEN 12 AND 13 → [flow_create_calendar (계획정지)]
├ CASE 시프트 종료: 시프트 종료 시각 ±5분 → [flow_log (정상 종료)]
├ CASE 정기점검: 마지막 정비일 +30일 경과 → [flow_create_calendar (정기점검)]
└ DEFAULT (비계획) → [flow_send_email (긴급)]

Muster J — Bidirektionale Synchronisation von Arbeitsaufträgen mit externem ERP​

Bidirektionale Spiegelung PlantPulse ↔ externes ERP.

입력 1: ERP → 플랜트펄스
[flow_on_webhook] → [flow_create_work_order]

입력 2: 플랜트펄스 → ERP
[flow_on_entity_event type='ENTITY_CREATED' WorkOrder]
→ [flow_script_filter (출처가 ERP 가 아닌 경우만)]
→ [flow_http_request (ERP REST PUT)]

Um eine Endlosschleife zu vermeiden, markieren Sie von außen eingehende Nachrichten mit metadata.source='ERP' und filtern Sie diese Nachricht im Flow der entgegengesetzten Richtung heraus.

Vorsichtsmaßnahmen bei der Industrieintegration​

PunktEmpfehlung
OPC-Write-Befehl erst nach Sicherheitsverriegelung veröffentlichenErst nach Bedienerbestätigung oder Durchlauf der automatischen Sicherheitsregel
PLC-Pollingintervall nicht zu kurz einstellenUnter 1 Sekunde Risiko einer starken CPU-Auslastung der PLC
Ressourcenlimit der Docker-Container des Edge-GerätsBei OPC-Erfassung + zusätzlichem Container Vorsicht bei CPU/Speicher über 80 %
In der Inbetriebnahmephase alle Befehle im Dry-Run-ModusNutzung der dry_run=true-Option von flow_edge_tag_write
Vorsorge für Stromausfall — nur persistenten Speicher-Trigger vertrauenflow_on_webhook usw. sind flüchtig, Domain-Ereignis-Trigger sind persistent

Cookbook für externe Systemintegration​

Sammlung von flow_http_request-Konfigurationen und Payload-Beispielen für häufig aufgerufene externe Systeme.

Slack — Incoming-Webhook-Benachrichtigung​

URL: https://hooks.slack.com/services/T0000/B0000/{secret}
Method: POST
Headers:
Content-Type: application/json
Body (body_template):
{
"text": "${data.title}",
"blocks": [
{ "type": "header", "text": { "type": "plain_text", "text": "${data.title}" } },
{ "type": "section", "text": { "type": "mrkdwn", "text": "*자산:* ${metadata.asset_id}\n*값:* ${data.value}\n*시각:* ${metadata.ts}" } }
]
}
  • Erfolg: 200 + Body ok
  • Fehlschlag: 400 (fehlerhafte Payload) / 404 (falsches Secret) / 429 (Aufrufbegrenzung pro Minute überschritten)
  • Empfehlung: flow_throttle mit max. 1× pro Minute verdrahten

Microsoft Teams — Webhook-Benachrichtigung​

URL: https://{org}.webhook.office.com/webhookb2/{id}/IncomingWebhook/{secret}
Method: POST
Headers:
Content-Type: application/json
Body:
{
"@type": "MessageCard",
"@context": "https://schema.org/extensions",
"themeColor": "FF0000",
"title": "${data.title}",
"sections": [{
"facts": [
{ "name": "자산", "value": "${metadata.asset_id}" },
{ "name": "값", "value": "${data.value}" },
{ "name": "시각", "value": "${metadata.ts}" }
]
}]
}

Verzweigen Sie themeColor nach FF0000 (Rot)/FFA500 (Orange)/00C853 (Grün), um die Priorität zu visualisieren.

Jira — Automatische Erstellung eines Issues​

URL: https://{org}.atlassian.net/rest/api/3/issue
Method: POST
Headers:
Authorization: Basic {base64(email:apitoken)}
Content-Type: application/json
Body:
{
"fields": {
"project": { "key": "OPS" },
"summary": "[자동] ${data.title}",
"description": {
"type": "doc",
"version": 1,
"content": [{
"type": "paragraph",
"content": [{ "type": "text", "text": "자산: ${metadata.asset_id}\n값: ${data.value}" }]
}]
},
"issuetype": { "name": "Bug" },
"priority": { "name": "High" }
}
}
  • Der Response-Body data.response_body.key enthält einen Issue-Key wie OPS-1234, den Sie in Folgenodes verwenden können
  • Fehlschlag: 400 (falsches Feld) / 401 (Authentifizierung) / 403 (keine Projektberechtigung)

GitHub Issues — Automatische Erstellung eines Issues​

URL: https://api.github.com/repos/{owner}/{repo}/issues
Method: POST
Headers:
Authorization: Bearer {pat_token}
Accept: application/vnd.github+json
Body:
{
"title": "[자동] ${data.title}",
"body": "자산: ${metadata.asset_id}\n값: ${data.value}\n시각: ${metadata.ts}\ntrace: ${metadata.trace_id}",
"labels": ["automation", "ops"]
}

ERP (SAP S/4HANA OData) — Ausstellung eines Arbeitsauftrags​

URL: https://{host}/sap/opu/odata/sap/API_MAINTNOTIFICATION/MaintenanceNotification
Method: POST
Headers:
Authorization: Basic {base64(user:pass)}
X-CSRF-Token: fetch ← 별도 GET 으로 토큰 받기
Content-Type: application/json
Body:
{
"NotificationType": "M2",
"MaintenanceNotificationType": "M2",
"TechnicalObject": "${metadata.asset_id}",
"NotificationText": "${data.title}",
"MalfunctionStartDate": "${data.start_date}",
"Priority": "${data.priority}"
}

Sie müssen zunächst per GET den CSRF-Token abrufen und dann mit demselben Sitzungscookie ein POST senden. Verbinden Sie zwei flow_http_request-Nodes und leiten Sie den Token aus dem Response-Header des ersten Nodes an den Header des zweiten Nodes weiter.

MES (direktes INSERT in externe DB) — flow_jdbc_query​

Direktes Einfügen einer Zeile in die Arbeitsauftragstabelle eines externen MES-Systems.

INSERT INTO mes.work_order
(order_no, asset_id, product_id, qty, status, due_date, created_by)
VALUES
(:order_no, :asset_id, :product_id, :qty, 'NEW', :due_date, 'flow')
Node-OptionWert
datasource_idmes_db (vorab in der Systemeinstellung registriert)
queryobiges SQL
binds{"order_no":"${data.order_no}","asset_id":"${metadata.asset_id}",...}

flow_jdbc_query unterstützt neben SELECT auch INSERT/UPDATE/DELETE. Die Transaktion wird pro Node automatisch committed/zurückgerollt.

Grafana — Benachrichtigung bei automatischer Aktualisierung des Dashboards​

URL: https://{host}/api/annotations
Method: POST
Headers:
Authorization: Bearer {api_key}
Content-Type: application/json
Body:
{
"dashboardUID": "...",
"panelId": 4,
"time": ${metadata.ts},
"tags": ["alarm", "${metadata.asset_id}"],
"text": "${data.title}"
}

Bei Alarmauftreten wird auf dem Graphen automatisch ein Marker angezeigt — sehr nützlich für die nachträgliche Analyse.

Telegram — Bot-Nachricht​

URL: https://api.telegram.org/bot{token}/sendMessage
Method: POST
Body:
{
"chat_id": "-1001234567890",
"text": "🚨 *${data.title}*\n자산: `${metadata.asset_id}`\n값: ${data.value}",
"parse_mode": "Markdown"
}

Schnellübersicht REST-Authentifizierungsmuster​

AuthentifizierungsmethodeHeader
API Key (Header)X-API-Key: {token}
API Key (Query)am Ende der URL ?api_key={token}
Bearer TokenAuthorization: Bearer {token}
Basic AuthAuthorization: Basic {base64(user:pass)}
OAuth2 (Client Credentials)Token-Ausstellung → Bearer-Header (Erneuerung über separaten Node)
HMAC-Signaturbody-/zeitbasierte Signatur per Skript berechnen und im X-Signature-Header

Muster zur Antwortparsierung​

Verwenden Sie nach der flow_http_request-Antwort data.response_body im nächsten Node:

// 응답에서 ID 추출
data.created_id = data.response_body.id;
data.status = data.response_body.status;

// 응답 배열에서 첫 행만
data.first_item = (data.response_body.items || [])[0] || null;

// 응답이 문자열이면 JSON 파싱
if (typeof data.response_body === 'string') {
try { data.response_body = JSON.parse(data.response_body); } catch (e) {}
}
msg

Sicherheitsempfehlungen beim Aufruf externer Systeme​

PunktEmpfehlung
Token nicht im Klartext im Graphen belassenNach Registrierung im Speicher für Anmeldedaten der Systemeinstellung wie ${creds.slack_webhook} referenzieren
Bei sensiblen Informationen im Response-Body maskierenMit flow_script_transform PII/Token entfernen und dann an den nächsten Node
Separate Retry-Richtlinie je externes SystemWo die Aufrufhäufigkeit hoch ist, separat flow_retry + flow_throttle verdrahten
Aufrufergebnis als Audit-Log speichernMit flow_save_attributes Aufruf-Historienmetadaten zur Anlage hinzufügen

Cookbook für Datentransformation​

Sammlung von Transformationsmustern, die Sie unverändert in den Node flow_script_transform übernehmen können. Alle Beispiele basieren auf JavaScript und verwenden die Kurzaliase data / metadata.

Einheitenumwandlung​

// 섭씨 → 화씨
data.temp_f = data.temp_c * 9 / 5 + 32;

// 바 → kPa
data.pressure_kpa = data.pressure_bar * 100;

// rpm → rad/s
data.angular_velocity = data.rpm * 2 * Math.PI / 60;

// kWh → MJ
data.energy_mj = data.energy_kwh * 3.6;

// 바이트 → MB (소수 1자리)
data.size_mb = Math.round(data.bytes / 1024 / 1024 * 10) / 10;

msg

Datums-/Zeitumwandlung​

const d = new Date(metadata.ts);

// ISO 8601 — 2026-05-12T12:34:56.789Z
data.iso = d.toISOString();

// 사람용 — 2026-05-12 21:34:56 (KST)
data.local = d.toLocaleString('ko-KR', { hour12: false });

// 날짜만 — 2026-05-12
data.date = d.toISOString().slice(0, 10);

// 시간만 — 21:34:56
data.time = d.toTimeString().slice(0, 8);

// 분 단위로 내림 (스파크라인 키)
data.minute_key = Math.floor(metadata.ts / 60000) * 60000;

// 시간 단위로 내림
data.hour_key = Math.floor(metadata.ts / 3600000) * 3600000;

// 한국 시간 (UTC+9) 직접 더하기 (서버 시간이 UTC 인 경우)
data.kst_hour = new Date(metadata.ts + 9 * 3600000).getUTCHours();

msg

Stringnormalisierung​

// 공백 trim + 소문자화
data.normalized = (data.text || '').trim().toLowerCase();

// 한글·영문 외 제거 (특수문자/공백 정리)
data.clean = (data.text || '').replace(/[^가-힣a-zA-Z0-9]/g, '');

// camelCase → snake_case
data.snake = (data.text || '').replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');

// 전화번호 정규화 (숫자만)
data.phone_digits = (data.phone || '').replace(/\D/g, '');

// 한국 휴대전화 자동 포맷 (010-1234-5678)
const p = (data.phone || '').replace(/\D/g, '');
data.phone_formatted = p.length === 11 ? p.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3') : p;

msg

Abflachen verschachtelter Objekte​

// data.location.address.city → data.city
function flatten(obj, prefix, out) {
out = out || {};
for (var k in obj) {
var v = obj[k];
var key = prefix ? prefix + '_' + k : k;
if (v && typeof v === 'object' && !Array.isArray(v)) flatten(v, key, out);
else out[key] = v;
}
return out;
}
data = flatten(data);
msg

Flaches Objekt → verschachtelt​

// data.user_name + data.user_email → data.user = {...}
function unflatten(obj) {
var out = {};
for (var k in obj) {
var parts = k.split('_');
var cur = out;
for (var i = 0; i < parts.length - 1; i++) {
cur[parts[i]] = cur[parts[i]] || {};
cur = cur[parts[i]];
}
cur[parts[parts.length - 1]] = obj[k];
}
return out;
}
data = unflatten(data);
msg

CSV-Zeilenerstellung​

// 외부 시스템에 CSV 한 줄 보낼 때
function csvEscape(v) {
if (v === null || v === undefined) return '';
v = String(v);
return /[,"\n]/.test(v) ? '"' + v.replace(/"/g, '""') + '"' : v;
}
data.csv_row = [
csvEscape(metadata.ts),
csvEscape(metadata.asset_id),
csvEscape(data.value),
csvEscape(data.quality)
].join(',');
msg

Array-Aggregation​

var arr = data.values || [];

// 합·평균·최소·최대
data.sum = arr.reduce(function(a, b) { return a + b; }, 0);
data.avg = arr.length ? data.sum / arr.length : 0;
data.min = arr.length ? Math.min.apply(null, arr) : null;
data.max = arr.length ? Math.max.apply(null, arr) : null;

// 중앙값
var sorted = arr.slice().sort(function(a, b) { return a - b; });
var mid = Math.floor(sorted.length / 2);
data.median = sorted.length === 0 ? null
: sorted.length % 2 ? sorted[mid]
: (sorted[mid - 1] + sorted[mid]) / 2;

msg

Bedingtes Hinzufügen von Feldern (Schema-Evolution)​

// 알람 우선순위에 따라 색상·아이콘 자동 부여
var p = data.priority || 'INFO';
data.color = { ERROR: '#d32f2f', WARN: '#f57c00', INFO: '#1976d2' }[p] || '#9e9e9e';
data.icon = { ERROR: '🔴', WARN: '🟠', INFO: '🔵' }[p] || '⚪';
data.urgency = p === 'ERROR' ? 3 : p === 'WARN' ? 2 : 1;
msg

Maskierung eines Teils der Payload​

function maskEmail(e) {
if (!e || e.indexOf('@') < 0) return e;
var parts = e.split('@');
return parts[0].slice(0, 2) + '***@' + parts[1];
}
function maskPhone(p) {
return (p || '').replace(/(\d{3})\d{4}(\d{4})/, '$1-****-$2');
}
data.user_email = maskEmail(data.user_email);
data.user_phone = maskPhone(data.user_phone);
msg

Mehrsprachige (i18n) Vorlage​

// 메시지 본문을 사용자 로케일에 따라 분기
const tpl = {
'ko-KR': '🚨 ${asset} 온도 ${value}°C 임계 초과',
'en-US': '🚨 ${asset} temperature ${value}°C exceeds threshold',
'ja-JP': '🚨 ${asset} 温度 ${value}°C 閾値超過'
};
const locale = metadata.user_locale || 'ko-KR';
const template = tpl[locale] || tpl['ko-KR'];
data.notification = template
.replace('${asset}', metadata.asset_id)
.replace('${value}', data.value);
msg

Sichere JSON-Path-Abfrage​

// data.deep.nested.field 처럼 깊은 경로를 안전하게 조회
function get(obj, path, dflt) {
var keys = path.split('.');
var cur = obj;
for (var i = 0; i < keys.length; i++) {
if (cur === null || cur === undefined) return dflt;
cur = cur[keys[i]];
}
return cur === undefined ? dflt : cur;
}
data.city = get(data, 'location.address.city', 'Unknown');
msg

Nachrichtenzusammenführung (flow_merge-Nachbearbeitung)​

// flow_merge 가 data.merged 배열로 모은 메시지들을 1건으로 합침
var items = data.merged || [];
data.summary = {
count: items.length,
first_ts: items[0]?.metadata?.ts,
last_ts: items[items.length - 1]?.metadata?.ts,
assets: Array.from(new Set(items.map(function(m) { return m.metadata?.asset_id; }))),
max_value: Math.max.apply(null, items.map(function(m) { return m.data?.value || 0 }))
};
delete data.merged;
msg

Sammlung wiederverwendbarer Skripte​

Skriptbibliothek, die Sie unverändert in die Nodes flow_script_filter / flow_script_transform / flow_switch übernehmen können. Alle Skripte basieren auf JavaScript und verwenden die Kurzaliase data / metadata.

Transformationsskripte​

Einheitenumwandlung·Etikettierung​

// 섭씨 → 화씨 + 등급 라벨
data.temp_f = data.temp * 1.8 + 32;
data.grade = data.temp > 80 ? 'HIGH' : data.temp < 0 ? 'LOW' : 'OK';
msg

Ergänzung von Zeit-·Schicht-·Wochentag-Metadaten​

const d = new Date(metadata.ts);
const h = d.getHours();
metadata.shift = (h >= 6 && h < 14) ? 'A' : (h < 22) ? 'B' : 'C';
metadata.weekday = ['SUN','MON','TUE','WED','THU','FRI','SAT'][d.getDay()];
metadata.is_weekend = (d.getDay() === 0 || d.getDay() === 6);
msg

Berechnung des Alarmbands Durchschnitt ± 3σ​

const m = data.mean, s = data.stddev || 1;
data.tag_id = originator.id + '.TEMP';
data.hi = m + 3*s; data.lo = m - 3*s;
data.hi_hi = m + 4*s; data.lo_lo = m - 4*s;
data.use_alarm = true;
msg

Zuordnung MES PO → Arbeitsauftrag​

const po = data;
data = {
master_id: 'WO-MES-' + po.po_no,
asset_id: po.line_id || 'UNASSIGNED',
title: po.product_name + ' (' + po.qty + ')',
due_date: po.delivery_date,
qty: po.qty,
product_id: po.product_code
};
msg

Normalisierung externer Payload (Vereinheitlichung unterschiedlicher Feldnamen)​

// 외부 시스템에 따라 키 이름이 다른 경우 — 한 줄로 정규화
data.value = data.value ?? data.val ?? data.v;
data.timestamp = data.timestamp ?? data.ts ?? metadata.ts;
data.tag_id = data.tag_id ?? data.tagId ?? data.id;
msg

Kumulierung der Anzahl von Schwellenwertverletzungen (Stateful-Muster)​

// 자산 attribute 와 함께 사용 — 상태는 메시지 자체에 적재
data.consecutive_fail = (data.consecutive_fail ?? 0) + (data.passed ? 0 : 1);
data.alert = data.consecutive_fail >= 5;
msg

Zusammenfassung von Nachrichtenstatistiken (Aufbereitung des Merge-Ergebnisses)​

// flow_merge 후 data.merged 배열을 받아 요약
const arr = data.merged || [];
data.count = arr.length;
data.values = arr.map(m => m.data.value).filter(v => v != null);
data.mean = data.values.reduce((a,b)=>a+b, 0) / (data.values.length || 1);
data.max = Math.max(...data.values);
data.min = Math.min(...data.values);
delete data.merged;
msg

Anwendung zeitzonenabhängiger Schwellenwerte​

const h = new Date(metadata.ts).getHours();
const threshold = (h >= 8 && h < 18) ? 90 : 70; // 주간 90, 야간 70
data.alarm = data.value > threshold;
data.threshold = threshold;
msg

Filterskripte​

Prioritäts-Whitelist​

['ERROR', 'CRITICAL'].includes(data.priority)

Zeitfenster (nur werktags)​

const h = new Date(metadata.ts).getHours();
h >= 8 && h < 20

Muster von Anlagen-·Tag-ID​

/^MOTOR-.*$/.test(originator.id)
// 또는
metadata.tag_id && metadata.tag_id.startsWith('LINE-A.')

Schwellenwert + Stabilität (N-mal in Folge)​

data.value > 100 && (data.consecutive_count ?? 0) >= 5

Prüfung von Geschäftszeiten·Feiertagen​

const d = new Date(metadata.ts);
const h = d.getHours();
const wd = d.getDay();
// 평일 09-18시만 통과
wd >= 1 && wd <= 5 && h >= 9 && h < 18

Nur bestimmter Standort​

['SITE-01', 'SITE-02'].includes(metadata.site_id)

Prüfung, ob alle Pflichtfelder existieren​

data.value != null && data.tag_id && metadata.ts

Blockierung selbst veröffentlichter Nachrichten (bidirektionale Synchronisation)​

metadata.source !== 'flow'

Switch-Case-Skripte​

Nach Prioritätsstufe​

// case "Critical"
['CRITICAL', 'EMERGENCY'].includes(data.priority)

// case "High"
data.priority === 'ERROR'

// case "Normal"
['WARN', 'INFO'].includes(data.priority)

Nach Anlagenstatus​

// case "Running"
data.status === 'RUN'

// case "Stopped"
['STOP', 'IDLE', 'PAUSED'].includes(data.status)

// case "Faulted"
data.status === 'FAULT' || data.error_count > 0

Nach Arbeitsauftrags-Lebenszyklus​

// case "Start"
data.event_type === 'START_REQUEST'

// case "End"
data.event_type === 'COMPLETE' && data.qty_done >= data.qty_planned

// case "Abort"
data.event_type === 'CANCEL'

Die oben genannten Skripte fassen im Betrieb häufig verwendete Muster zusammen. Sie funktionieren auch, wenn sie direkt im Graphen verdrahtet werden; passen Sie lediglich Schwellenwerte·Feldnamen an Ihre Domäne an.


Glossar​

Fachbegriffe der Flow-Engine​

BegriffBedeutung
entity_typeArt der Subjekt-Entität der Nachricht — z. B. Asset, Tag, Site, Order, Customer, Product, Employee, Calendar
originatorSubjekt-Entität, auf die sich die Nachricht bezieht (entity_type + id). Beispiel: Asset/MOTOR-001
typeKlassifizierungslabel der Nachricht. Identifiziert, welche Art von Ereignis der Trigger empfangen hat
dataInhalt (Payload) der Nachricht — wird hauptsächlich von Transformations-·Aktionsnodes gelesen und geschrieben
metadataKontext der Nachricht (Zeit·Standort·Schicht·Tag-ID usw.) — bleibt auch nach Transformation bis zum Ende des Ablaufs erhalten
relationLabel des Ausgangs-Wires eines Nodes. SUCCESS/FAILURE/TRUE/FALSE/MATCH/NO_MATCH/DEFAULT/THROTTLED/EXHAUSTED (alle Großbuchstaben)
*_field dynamische OptionEingabeart, die statt eines statischen Werts einen Wert aus einem Pfad der Nachrichten-Payload liest (z. B. data.tag_id)
Glob-MusterWildcard-Ausdruck der Trigger-Option *_pattern — * passt auf 0 oder mehr Zeichen, ? passt auf genau 1 Zeichen
SnapshotBeim Graph-Speichern automatisch angelegtes versionsweises Backup. Wird bei Vorfällen zum Zurücksetzen auf einen vorherigen Zustand verwendet
Teilaktualisierung (fetch+merge)Methode, bei der der Update-Node nach Abfrage des bestehenden Datensatzes nur die eingegebenen Felder zusammenführt. Leere Werte werden ignoriert
SKIPPEDBehandlung, bei der eine nicht mit dem Trigger-Muster übereinstimmende Nachricht nicht an Folgenodes fließt und auch aus dem Zähler ausgeschlossen wird
EXHAUSTEDZweig, der ausgelöst wird, wenn der flow_retry-Node die maximale Anzahl von Wiederholungen überschreitet
THROTTLEDZweig, der ausgelöst wird, wenn der flow_throttle-Node Nachrichten blockiert, die das Limit im Fenster überschreiten

Domänen-·Abkürzungsglossar​

Eine Zusammenstellung von im Anlagenbetrieb häufig verwendeten Abkürzungen zur schnellen Referenz innerhalb dieses Handbuchs.

AbkürzungBedeutungIn diesem Handbuch
MESManufacturing Execution System — Verwaltung von Arbeitsauftrag·ProduktionsergebnisZiel externer Anbindung (HTTP/MQTT/externe DB)
ERPEnterprise Resource Planning — unternehmensweites Ressourcen-·PlanungssystemZiel externer Anbindung
SCADASupervisory Control and Data Acquisition — Überwachung·SteuerungZiel externer Anbindung / Ausgang von flow_publish_asset_command
OPCOpen Platform Communications — IndustriekommunikationsstandardZiel der Edge-Kategorie (flow_edge_opc_*)
OEEOverall Equipment Effectiveness — Verfügbarkeit × Leistung × Qualitätflow_on_oee_event-Trigger
RAMReliability·Availability·Maintainabilityflow_on_ram_event-Trigger
EMSEnergy Management Systemflow_on_ems_event-Trigger
EQLDomain-Ereignisregelausdrucklanguage: "EQL"-Option von flow_script_filter/flow_script_transform
CEPComplex Event ProcessingEQL-basierte Regel-Engine. Alarme müssen ausschließlich über den CEP-Pfad entstehen, um Konsistenz zu gewähren
POPurchase Order — Bestell-·ProduktionsauftragEinheit, die bei der MES-Anbindung in einen Arbeitsauftrag umgewandelt wird
WOWork Order (Arbeitsauftrag)flow_*_work_order-Node-Gruppe
CMMSComputerized Maintenance Management SystemZiel externer Anbindung
MTTF/MTTRMean Time To Failure / To RepairKernkennzahl von RAM-Ereignissen
HMIHuman–Machine InterfaceBedienbildschirm von SCADA usw.

Versionshinweise​

Einführungszeitpunkte der wichtigsten Funktionsgruppen, die dieses Handbuch derzeit behandelt. Wenn Sie eine ältere Version betreiben, kann sich manches Verhalten unterscheiden.

V2026.05 — Erweiterung der Domänen-Automatisierung​

  • 11 Edge-Kategorien (Edge) neu eingeführt — Automatisierung von OPC-Server/Tag-CRUD + Monitoring
  • 5 Zustandsübergänge des Arbeitsauftrags — flow_start/end/pause/resume/abort_work_order
  • 2 Teilaktualisierungen des Tag-Alarmbands — Aktualisierung nur eingegebener Felder von numerischem/booleschem Alarmband
  • Neuer flow_retry Ablaufsteuerungs-Node — Backoff + maximale Versuche + EXHAUSTED-Zweig
  • 5 neue Trigger — flow_on_asset_health_status / _connection_status / _oee_event / _ram_event / _ems_event
  • Teilaktualisierung des Update-Nodes (fetch+merge) — Zusammenführung nur der eingegebenen Felder nach Abfrage des bestehenden Datensatzes
  • Großbuchstaben-Standardisierung der Relations — SUCCESS/FAILURE/... alle in Großbuchstaben, bestehende Graphen werden automatisch konvertiert
  • SKIPPED-Behandlung — Ausschluss von nicht mit dem Trigger-Muster übereinstimmenden Nachrichten aus dem Zähler
  • Betriebswerkzeug „Alle neu bereitstellen (redeploy)“ — Massen-Neuladen aktiver Flows
  • Alle Zähler zurücksetzen — Massenreset der Statistik auf Node- und Flow-Ebene

V2026.03 — Release-Stabilität​

  • Automatischer Snapshot beim Graph-Speichern
  • Live-Debug-Panel (Aktualisierung alle 2 Sekunden unter dem Inspektor) + Node-Leuchtanzeige·Duration-Anzeige
  • Import/Export (Graph-JSON-Datei)
  • Einführung des Last-Watchdogs — Ausgabe eines Diagnoseprotokolls bei anhaltender Last

Davor​

  • M1 — Engine-·UI-Grundgerüst, Graph-CRUD, visuelle Canvas
  • M2 — Domain-Aktionsnodes (Anlage·Tag·Arbeitsauftrag·Produktionsdomäne usw.)
  • M3 — Diversifizierung der Trigger, 8 Arten von Filter/Transformation/Externer Anbindung, Skript-Engine
  • M4 — Debug-Laden·Ausführungshistorie-Bildschirm, Statistik, Bereitstellen/Aufheben, Import/Export
  • M5 — Integration der Domain-Trigger, Massenverifizierung von Szenarien

Alle in diesem Handbuch behandelten Funktionen und Verhalten basieren auf dem oben genannten Zeitpunkt V2026.05.


Verwandte Bildschirme​

  • CEP (Complex Event Processing): EQL-basierte Domain-Ereignisregel-Engine
  • Alarm: Alarmauftreten·Historie
  • Datenpunkt: Abfrage·Analyse von Tag-Daten
  • Entwicklerhandbuch: Flow-Engine: Engine-Architektur·Node-Schnittstelle·DB-Schema