Wie es funktioniert
PDC Edge ist der einzige Besitzer der Steuerungsverbindungen einer Anlage. DF, Node-RED und Dritt-Software lesen und schreiben über die Edge – nicht mehr direkt auf der Steuerung.
- Siemens S7
- OPC UA
- Modbus TCP
- Rockwell EtherNet/IP
- MQTT
- HTTP
- CoAP
- SignaleAdresse, Datentyp, Zugriff
- VerarbeitungProzessoren und JavaScript
- Datenmodellevirtuelle Signale, Kontext
- UNS über MQTT
- Kafka
- REST und WebSocket
- Node-RED
- Autexis DF 4.0
- MES, ERP, Cloud
- eigene Anwendungen
Schreibaufträge der Nutzer laufen über das Write-Gate geprüft zurück zur Steuerung.
- ErfassenTreiber lesen Steuerungen und Nachrichtenquellen. Jede Quelle wird einmal als Signal adressiert.
- AufbereitenPro Signal läuft eine Verarbeitungskette: skalieren, filtern, Vorwerte verrechnen, eigene Logik in JavaScript.
- BereitstellenJeder Wert erhält einen stabilen Pfad im Unified Namespace (UNS) und ist über MQTT, Kafka, REST, WebSocket und Node-RED erreichbar.
- ZurückschreibenJeder Schreibauftrag läuft durch dasselbe Write-Gate – egal über welchen Kanal er kommt.
Nicht alle gezeigten Protokolle und Kanäle sind heute umgesetzt. Der Stand pro Baustein steht in den Tabellen der drei Bereiche.
Ein Ort für alle Steuerungsdaten – lesend und schreibend
PDC Edge ist die vollständige Neuentwicklung der Prozessdatenerfassung (PDC) der Autexis Digital Factory. Sie läuft als eigenständige Edge-Komponente auf Industrie-PC, ARM-Edge-Box, VM oder Docker und ersetzt PDC v1 vollständig.
Nutzen
- Jede Anwendung baut eigene Verbindungen zu denselben Steuerungen.
- In PDC v1 liegt die Logik im Node-RED-Gateway. Schreiben auf die Anlage ist nicht vorgesehen.
- Konfigurationsänderungen haben keine Revision und keine Quittung.
- Die Edge ist der einzige Device-Owner der Anlage.
- Signale werden einmal sauber konfiguriert und überall gleich genutzt.
- Die Konfiguration ist ein versioniertes Dokument mit Diff und Rollback.
- Jeder Wert hat einen stabilen Pfad im UNS.
- Jeder Schreibvorgang hat Absender, Korrelations-ID, Ergebnis und Audit-Eintrag.
- Neue Konsumenten werden angebunden, ohne die Steuerung erneut zu belasten.
Quelle: Vision und Scope (Kapitel 01, Ziele Z1–Z10). Die Ergebnisse beschreiben das Zielbild; der Umsetzungsstand steht unten unter «Status».
Ein besserer KEPServer
PDC Edge stellt sich bewusst dem Vergleich mit KEPServerEX. Die Planung nennt konkret, was besser sein soll – und wo die Grenzen liegen.
Ehrliche Grenze: KEPServerEX hat über 150 Treiber, PDC Edge startet mit sieben Protokollfamilien. Exotische Treiber wie Siemens S5 oder BACnet sind nicht geplant. Sie bleiben bei Bedarf beim KEPServer und werden über OPC UA oder MQTT an die Edge angebunden.
| Thema | PDC Edge |
|---|---|
| Plattform | Linux (Windows offen), amd64 und arm64, Container-nativ, Single Binary |
| Konfiguration | Deklaratives YAML/JSON mit JSON-Schema, Revisionen, Diff, Rollback, Git-tauglich |
| Datenverarbeitung | Eingebaute Verarbeitung: skalieren, Deadband, nur bei Änderung, Delta, Verrechnung mit Vorwerten, JavaScript |
| Bereitstellung | UNS nativ über MQTT, dazu Kafka, WebSocket und REST mit einheitlichem Topic- und Payload-Modell |
| Schreiben | Rechte pro UNS-Pfad und Signal, Anfrage mit Korrelations-ID, Timeout, Rücklese-Prüfung, Audit |
| Lizenz | Ein Produkt, keine Tag-Limits durch die Lizenz |
| DF-Integration | Konfiguration aus der DF, DF-Funktionen, Writes bei Custom Actions |
Stand-alone oder mit der DF
PDC Edge ist ohne DF voll funktionsfähig und separat lizenzierbar. Keine Funktion des Basisumfangs wird ohne DF künstlich begrenzt. Mit der DF erreichen Sie mehr: Was fachlich MES-Logik ist, etwa OEE, Zustandsmaschine oder Auftragsverwaltung, liefert die DF.
| Funktion | Stand-alone | Mit Autexis DF 4.0 | Stand |
|---|---|---|---|
| Steuerungen anbinden, Signale erfassen und verarbeiten | ja | ja | siehe Treiber |
| UNS, REST, WebSocket, Node-RED | ja | ja | in Entwicklung |
| Templates, Datenmodelle, virtuelle Signale, Kontext, Schreiben über UNS (MQTT) | ja | ja | geplant (M1/M1b) |
| Zentrale Konfiguration mehrerer Edges: Revisionen bearbeiten, ausrollen, zurückrollen, Status pro Instanz | – | ja | geplant (M2) |
| Maschinenzustände, Unterbrechungen, Sensoren, Equipment Notifications, Energie als DF-Bindings; OEE-Auswertung in der DF | – | ja | geplant (M2) |
| Auftragsdaten an die Anlage schreiben, z.B. Auftragsnummer bei Arbeitsgang READY (Write-Actions) | – | ja | geplant (M2/M3) |
| UNS-Knoten aus der DF-Hierarchie (Werk, Bereich, Arbeitsplatz) | – | ja | geplant (M2) |
| Anmeldung mit dem DF-Konto, DF-Rechte als Edge-Rollen | – | ja | geplant (M2) |
| DF-weiter Katalog für Datenmodelle und Templates | – | ja | geplant (M2/M3) |
| Langzeitdaten, Auswertungen, Dashboards, Exporte (die Edge ist bewusst kein Historian) | – | ja | im DF-Bestand |
| Migration von PDC v1 mit Schattenbetrieb | – | ja | geplant (M2) |
Sicherheit
Schreiben auf eine Anlage ist ein Eingriff in die Produktion. PDC Edge behandelt es so: Alles ist zunächst gesperrt und wird gezielt freigegeben.
Write-Gate Basis umgesetzt Vollumfang (M1)
Jeder Schreibauftrag durchläuft dieselbe Prüfkette – über REST, WebSocket, MQTT, Kafka, Node-RED oder die DF. Schreiben ist pro Gerät und pro Signal standardmässig aus. Wertebereiche, Rate-Limits und auf Wunsch eine Vier-Augen-Freigabe kommen dazu. Ein globaler Schreib-Notaus sperrt alle Writes.
Rollen und Rechte geplant (M1)
Feste Rollen viewer, operator, engineer, admin und auditor. Zusätzlich regeln Zugriffslisten pro UNS-Pfad oder Signal, wer was lesen oder schreiben darf.
Audit geplant (M1)
Alle Schreibversuche inklusive Ablehnungen, Freigaben, Konfigurationsänderungen und Anmeldungen landen in einem Audit-Log, das nur angehängt werden kann. Eine Hash-Kette macht nachträgliche Änderungen erkennbar.
Verschlüsselung und Zertifikate geplant (M1)
TLS für alle Netzwerkschnittstellen, keine Default-Passwörter. Passwörter und Schlüssel stehen nie im Konfigurationsdokument, nur als Verweis auf einen verschlüsselten Speicher. Der OPC-UA-Treiber prüft Server-Zertifikate über eine Trust-List ohne automatisches Vertrauen und sendet Passwörter nie im Klartext. OPC UA umgesetzt
Keine Safety-Funktion. Schreibzugriffe über PDC Edge sind nicht sicherheitsgerichtet (kein SIL/PL). Sicherheitsrelevante Verriegelungen bleiben in der Steuerung. S7, Modbus TCP und EtherNet/IP haben keine Transportsicherung; sie werden über Netzsegmentierung geschützt.
Betrieb
Ein Prozess, eine Datei, ein Datenverzeichnis. Die Benutzeroberfläche ist im Binary eingebettet. Lokale Daten liegen in SQLite: Konfiguration, Revisionen und Laufzeitzustände überstehen einen Neustart.
Zielwerte der Planung (noch nicht gemessen, Kapitel 01 §7): Latenz p99 ≤ 50 ms vom Treiber bis UNS auf einem Industrie-PC; Start bis API bereit ≤ 3 s; Abnahme M1 mit 20 000 Signalen pro Instanz auf Industrie-PC und 10 000 auf einer ARM-Edge-Box.
| Variante | Inhalt | Stand |
|---|---|---|
| Single Binary | Linux amd64 und arm64, UI eingebettet | umgesetzt |
| Docker | Multi-Arch-Image, Non-Root, Volume /data | umgesetzt |
| systemd | Unit mit Härtung, eigener Benutzer | umgesetzt |
| SBOM | CycloneDX und SPDX aus der CI | umgesetzt |
| Metriken, Backup/Restore | Prometheus, SQLite-Online-Backup | geplant (M1) |
| Hochverfügbarkeit | Hot-Standby mit Leader-Lease, Cloud-Replika, Kubernetes | geplant (M4) |
| Windows-Dienst | Priorität noch offen (PO-Entscheid) | offen |
Status und Roadmap
Das Grundgerüst steht. Die Arbeiten am ersten produktiven Stand (M1, «MVP Stand-alone») laufen. Ein Release-Datum ist noch nicht festgelegt.
- M0Grundgerüst: Simulator → Verarbeitung → REST/WebSocket inklusive Schreiben, JavaScript-Verarbeitung, Builds für amd64 und arm64umgesetzt
- M1MVP Stand-alone: S7, OPC UA, Modbus TCP, MQTT; UNS über MQTT; Benutzer, Rollen, Write-Gate, Audit; UI. S7 und OPC UA sind umgesetztin Entwicklung
- M1bStandardisierung: Datenmodelle, Templates, virtuelle Signale und Kontext, Schreiben über UNS, neue Bedienführunggeplant (M1b)
- M2DF-Kopplung, DF-Bindings mit v1-Parität, Migration von PDC v1, Node-RED-Nodes vollständiggeplant (M2)
- M3Rockwell EtherNet/IP, Kafka, CoAP, DF-Write-Actions, eingebetteter MQTT-Brokergeplant (M3)
- M4Replikation, Hochverfügbarkeit, Cloud-Replikageplant (M4)
- M5OPC-UA-Server und Migrationshilfe für KEPServerEXgeplant (M5)
Quellen: Kapitel 10 (Meilensteine), CHANGELOG der Repos pdc-edge, pdc-edge-ui und node-red-contrib-autexis-pdc-edge. M1b ist als eigener Meilenstein beschlossen (PO-Entscheid E43).
Konfigurieren statt programmieren
Eine Edge-Instanz wird durch genau ein Konfigurationsdokument beschrieben (EdgeConfig). Es ist deklarativ, wird gegen ein JSON-Schema geprüft und als unveränderliche Revision aktiviert. Autorenformat ist YAML, gut geeignet für Git und Diff.
Vier Konfigurationsebenen
Ein Signal wird einmal adressiert und dann beliebig oft verarbeitet, publiziert und gebunden. Das ersetzt die acht Pfad/Adress-Paare pro Datenpunkt aus PDC v1.
Signale
Woher lesen, wohin schreiben: Geräte, Adresse, Datentyp, Zugriff, Erfassung.
devices signalsVerarbeitung
Pipeline pro Signal, virtuelle Signale, Ereignisse.
processing triggersDatenmodelle und UNS
Namespace-Baum, Kontext, Datenmodelle, Ausgabe an Sinks.
namespace publishingDF-Bindings
Nur gekoppelt: Signale an DF-Fachfunktionen binden.
df.bindingsTreiber und Adressen
Jeder Treiber versteht eine Kurzform der Adresse. Eine strukturierte Form ist ebenfalls möglich.
| Treiber | Adressbeispiel | Lesen / Schreiben | Stand |
|---|---|---|---|
Simulator sim | sine:period=60s,amp=10,offset=50 | Poll / ja | umgesetzt |
Siemens S7 s7 (S7comm, PUT/GET) | DB10.DBD4:REAL, DB10.DBX2.1, DB10.DBB20:STRING[32]; v1-Syntax DB10,REAL4 wird konvertiert | Poll / ja | umgesetzt |
OPC UA Client opcua | nsu=urn:siemens:plc1;s="DB_Press".Oil.Temp | Subscribe, Read / ja | umgesetzt |
Modbus TCP modbus | hr:100:f32:be, co:5 | Poll / ja | geplant (M1) |
MQTT Client mqtt | plant/press1/telemetry mit JSON-Pointer | Subscribe / Publish | geplant (M1) |
HTTP-Ingress http (v1-kompatibel /pdc/<route>) | /pdc/press1#/oil/temp | Push / – | geplant (M1) |
HTTP-Client-Polling http | GET /api/values mit Extraktion | Poll / Request | geplant (M3) |
Rockwell EtherNet/IP eip | Program:Main.Counter[3].ACC | Poll / ja | geplant (M3) |
CoAP coap | /sensors/temp | Poll, Observe / ja | geplant (M3) |
Kafka als Quelle kafka | topic#jsonPointer | Consume / – | geplant (M3) |
Templates für gleiche Steuerungen geplant (M1/M1b)
Ein Device-Template beschreibt eine Steuerung mit Signalen, Verarbeitung, Knoten und Modellinstanzen. Eine weitere Anlage desselben Typs braucht nur noch Verbindungsdaten und Parameter. Abweichungen einzelner Anlagen werden als Overrides sichtbar markiert.
- Ziel: weitere Steuerung in höchstens 4 Assistentenschritten, ohne ID oder Adresse zu tippen.
- Viele Anlagen auf einmal per CSV.
- Ableitung, Versionen und Rollout mit Vorschau pro Instanz folgen in M2.
templateInstances:
- id: press1
name: "Presse 1"
template: s7-press@2.1.0
arguments:
host: 10.10.3.21
node: linie3-presse1
db: 10
zones: 6
plcPassword: "secret://s7/press1"
exclude: [ zone-6-temp ]
overrides:
oil-temp: { processing: [ { type: deadband, absolute: 1.0 } ] }Virtuelle Signale und Kontext geplant (M1/M1b)
Nicht jeder Wert kommt aus einer Steuerung. Virtuelle Signale sind vollwertige Signale mit UNS-Topic, Kontext und Modellzuordnung. Es gibt drei Quellenarten:
compute
Berechnet aus anderen Signalen per JavaScript-Ausdruck, nur lesend.
external
Aus einem fremden UNS- bzw. MQTT-Topic, z.B. die Auftragsnummer, die das MES publiziert.
manual
Gesetzt per Schreibauftrag, z.B. durch den Schichtleiter. Läuft durch das Write-Gate.
Beispiel: Auftragsnummer aus dem MES als Kontext
Das MES publiziert den laufenden Auftrag der Linie 3. Die Edge liest ihn als virtuelles Signal und hängt ihn als Kontext an alle Signale der Linie. Hübe und Temperaturen erscheinen dann im UNS mit Auftragsnummer – obwohl die Steuerungen keine kennen.
Kontext mit Zuordnung «letzter Wert» (latest) ist für M1/M1b geplant, die zeitgenaue Zuordnung (asOf) für M2.
signals:
- id: line3-order-no
dataType: string
access: read
source:
kind: external
broker: { sink: uns-main }
topic: acme/werk1/presswerk/linie3/order/current
extract: { jsonPointer: /orderNo }
timestamp: { jsonPointer: /validFrom }
initial: null
namespace:
nodes:
- id: linie3
slug: linie3
level: line
parent: presswerk
context:
orderNo: line3-order-no # Kurzform, join latestSchreiben mit Freigabe
Ein Write wird nur ausgeführt, wenn alle Bedingungen erfüllt sind. Fehlt eine, lehnt die Edge ab, ohne das Gerät zu berühren, und meldet den Grund.
Die Schreibbereitschaft eines Signals lässt sich vorab prüfen, ohne zu schreiben: GET /api/v1/signals/{id}/write-readiness liefert die Checkliste pro Kanal. geplant (M1/M1b)
| Bedingung | Wo eingestellt |
|---|---|
| Gerät erlaubt Writes | devices[].writePolicy.allowWrites |
| Signal beschreibbar und freigegeben | access: readWrite, write.enabled |
Kanal freigegeben (uns immer explizit) | write.channels, Default [api, dfLink, local] |
| Recht des Absenders | Rolle mit write:value und ACL write |
| Wert zulässig | write.min, write.max, write.pattern |
| Kein Schreib-Notaus aktiv | POST /api/v1/system/write-lock |
| Optional: Vier-Augen-Freigabe | write.approval: fourEyes |
Inbetriebnahme
Der Ablauf folgt der Logik der Ebenen. Jede Änderung entsteht zuerst als Entwurf und wird erst nach der Prüfung als Revision aktiv.
- Edge installierenBinary mit systemd oder Docker-Image starten, Datenverzeichnis festlegen. Beim ersten Start erzeugt die Edge ein eigenes TLS-Zertifikat.
- Konfiguration prüfen
pdc-edge validate <datei>prüft Schema und Semantik und endet mit Exit-Code 1 bei Fehlern. - Geräte anlegen und Verbindung testenVerbindungstest mit den Entwurfseinstellungen, ohne zu aktivieren (
POST /devices/{id}/test, M1). - Signale anlegenEinzeln, aus einem Template, per CSV-Import oder per Browse des Adressraums (OPC UA).
- Verarbeitung festlegen und testenProzessoren konfigurieren, JavaScript im Dry-Run gegen Beispielwerte prüfen.
- Namespace und Ausgabe festlegenUNS-Baum nach ISA-95 aufbauen, Sinks und Routen für MQTT bzw. Kafka definieren.
- Schreiben freigebenNur die nötigen Signale und Kanäle freigeben, Schreibbereitschaft prüfen.
- Prüfen und aktivierenDiff und Befunde in der Prüfansicht ansehen, Revision aktivieren. Ein Rollback auf eine frühere Revision ist jederzeit möglich.
Quellen: Kapitel 02 §7, 03 §8–§9, 16 §4. Die geführten UI-Abläufe sind für M1/M1b geplant; bis dahin sind die Funktionen über YAML und API nutzbar.
Testen ohne Hardware
Getestet wird ausschliesslich über Software-Simulation. Die Simulatoren sind Testwerkzeuge und nicht Teil des Produkts.
| Werkzeug | Zweck | Stand |
|---|---|---|
Treiber sim | Sinus, Rampe, Zähler, Rechteck, Speicherzelle | umgesetzt |
pdc-s7-sim | S7comm-Server mit Fehlerinjektion (Abbruch, Verzögerung, kleine PDU, Fragmentierung) | umgesetzt |
pdc-opcua-sim | OPC-UA-Server mit Testadressraum, Security-Endpoints, Fehlerinjektion | umgesetzt |
# Terminal 1: Simulator auf Port 1102
cargo run -p pdc-s7-sim -- --listen 127.0.0.1:1102
# Terminal 2: Edge gegen den Simulator (ohne Auth, nur Entwicklung)
cargo run -p pdc-edge -- run --config examples/s7-simulator.yaml --auth dev
curl -s localhost:8080/api/v1/signals/s7-oil-temp/valueMigration von PDC v1 geplant (M2)
Umgestellt wird pro Workplace und Funktion, nicht pro Gateway. Pro Workplace und Funktion gibt es genau einen Owner – das verhindert Doppelbuchungen in der DF. Ein Importer übernimmt die v1-Konfiguration, eine CLI pdc-edge migrate v1 dient der Offline-Analyse.
- Importv1-Konfiguration als Entwurf importieren, Migrationsbericht prüfen und nacharbeiten.
- SchattenbetriebEdge koppeln, Revision ausrollen. Die Edge rechnet mit, sendet aber nicht an die DF.
- VergleichMindestens eine Schicht lang Edge-Ergebnisse mit den v1-Buchungen in der DF vergleichen.
- UmschaltenOwnership je Funktion auf v2 stellen: Sensor, Energie, Equipment Notification, Unterbrechung, Maschinenzustand.
- BeobachtenMindestens eine Woche. Ein Rollback auf v1 wirkt sofort, ohne Deployment.
- Aufräumenv1-Nodes aus den Flows entfernen, Flows auf die Node-RED-Nodes von PDC Edge umstellen.
Quelle: Kapitel 08 §12, ADR 0032.
Ein Wertmodell, vier Zugänge
REST, WebSocket, MQTT und Kafka teilen dasselbe Wertobjekt und dasselbe Ergebnis-Vokabular für Writes. Die maschinenlesbare Quelle ist die OpenAPI 3.1 unter GET /api/v1/openapi.json, das WebSocket-Protokoll steht als JSON-Schema unter GET /api/v1/stream/schema.json.
Authentisierung
Basis-Pfad /api/v1, JSON mit Feldnamen in camelCase, Zeitstempel RFC 3339 UTC mit Millisekunden. Tokens gehören nie in URLs, auch nicht beim WebSocket.
API-Token für Node-RED und einfache Dritt-Software: Authorization: Bearer pdcat_<tokenId>_<secret>. Ein Bootstrap-Token lässt sich heute über PDC_API_TOKEN setzen. umgesetzt
Benutzerverwaltung, JWT für die UI, OIDC und Client-Credentials: geplant (M1/M3)
| Rolle | Fähigkeiten |
|---|---|
viewer | read:value, read:config, read:diagnostics |
operator | viewer + write:value, approve:write |
engineer | operator + write:config, activate:config, browse:device |
admin | alle |
auditor | read:audit |
REST Basis umgesetzt
Umgesetzt sind health, info, signals, value, values und write. Der übrige Vertrag (Konfiguration, Revisionen, Audit, Freigaben) ist für M1 geplant.
Wert lesen
curl -s https://pdc-edge:8443/api/v1/signals/press1-temp-oil/value \
-H "Authorization: Bearer $PDC_API_TOKEN"
{
"signal": "press1-temp-oil",
"uns": "acme/werk1/presswerk/linie3/presse1/oil-temperature",
"v": 72.4,
"q": "good",
"reason": null,
"sourceTs": "2026-11-13T09:15:02.470Z",
"edgeTs": "2026-11-13T09:15:02.481Z",
"unit": "°C",
"rev": 42
}q ist good, uncertain oder bad. Mehrere Werte: GET /api/v1/values?select=acme/werk1/%23 (Selektor mit +/# oder id:<glob>).
Wert schreiben
curl -s -X POST https://pdc-edge:8443/api/v1/signals/press1-orderno/write \
-H "Authorization: Bearer $PDC_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"value": "A-2026-004711",
"correlationId": "01JCA0V8Q3H4X9M2N5P7R1T6YB",
"timeoutMs": 5000,
"verify": "readBack",
"wait": true,
"comment": "Auftragsstart Linie 3"
}'
{
"writeId": "01JCA0V8R0000000000000000A",
"correlationId": "01JCA0V8Q3H4X9M2N5P7R1T6YB",
"signal": "press1-orderno",
"status": "succeeded",
"reason": null,
"value": "A-2026-004711",
"rawValue": "A-2026-004711",
"verified": true,
"requestedAt": "2026-11-13T09:20:00.010Z",
"completedAt": "2026-11-13T09:20:00.094Z",
"deviceTs": null,
"message": null
}status | Bedeutung | HTTP |
|---|---|---|
succeeded | Vom Gerät bestätigt, ggf. zurückgelesen | 200 |
pendingApproval | Wartet auf Vier-Augen-Freigabe | 202 |
rejected | Von der Edge abgelehnt, Gerät nicht berührt; Grund in reason (z.B. forbidden, writeDisabled, valueOutOfRange) | 4xx, 503 |
failed | Gerät hat abgelehnt oder Rücklesen weicht ab | 502 |
timeout | Keine Antwort in timeoutMs, Ausführung ungewiss | 504 |
WebSocket /api/v1/stream Basis umgesetzt
Subprotokoll pdc-edge.v1. Maschinen authentisieren sich mit dem Authorization-Header beim Upgrade, Browser mit dem Feld token im hello. Anfragen tragen eine vom Client gewählte reqId.
{ "type": "hello", "reqId": "h1", "client": "node-red/gw-hall1",
"version": "2027.1.0", "apiVersions": ["1"] }
{
"type": "subscribe",
"reqId": "s1",
"subId": "in-node-4711",
"select": ["acme/werk1/presswerk/linie3/#", "id:press1-*"],
"options": {
"snapshot": true,
"minIntervalMs": 250,
"maxBatch": 500,
"includeMeta": false,
"overflow": "dropOldest"
}
}{
"type": "value",
"subId": "in-node-4711",
"initial": false,
"items": [
{ "signal": "press1-temp-oil", "v": 72.4, "q": "good",
"edgeTs": "2026-11-13T09:15:02.481Z" }
]
}
{
"type": "write",
"reqId": "w1",
"signal": "press1-orderno",
"value": "A-2026-004711",
"correlationId": "01JCA0V8Q3H4X9M2N5P7R1T6YB",
"verify": "readBack",
"timeoutMs": 5000
}Die Antwort auf write heisst write_result – auch bei Ablehnung. error ist für Protokollfehler reserviert. Weitere Typen: read/readResult, unsubscribe, event, ping/pong.
Unified Namespace über MQTT geplant (M1)
Topics folgen ISA-95. <node> ist die Kette der Namespace-Knoten, <signal> der UNS-Name des Signals. Systemsegmente beginnen mit _.
| Zweck | Topic | Retain |
|---|---|---|
| Wert | <prefix>/<node>/<signal> | ja |
| Metadaten | …/<signal>/_meta | ja |
| Write-Anfrage | …/<signal>/_write | nein |
| Ereignis | <prefix>/<node>/_events/<triggerId> | nein |
| Instanz-Status | <prefix>/<site>/_pdc/<instanceId>/status | ja |
{
"value": 184223,
"quality": "good",
"ts": "2026-11-13T09:41:12.381Z",
"sourceTs": "2026-11-13T09:41:12.377Z",
"seq": 991
}Schreiben über UNS geplant (M1/M1b)
Ein Client publiziert auf …/_write und bekommt das Ergebnis auf sein Antwort-Topic. Ein Ablauf ist Pflicht, retained Anfragen werden verworfen. Writes über externe Broker sind standardmässig aus; das Signal muss den Kanal uns freigeben, und ein Auth-Modus (token oder brokerAcl) ist Pflicht.
Topic: acme/werk1/presswerk/linie3/presse1/order-no/_write
MQTT 5: Response Topic = clients/mes-01/replies, Correlation Data = 01JCA0V8Q3H4X9M2N5P7R1T6YB,
Message Expiry = 10, User Property authorization = Bearer <Edge-JWT>
Payload: {"value":"A-2026-004711","correlationId":"01JCA0V8Q3H4X9M2N5P7R1T6YB","timeoutMs":3000}
Topic: clients/mes-01/replies
Payload: {"correlationId":"01JCA0V8Q3H4X9M2N5P7R1T6YB","signal":"press1-orderno",
"status":"succeeded","reason":null,"durationMs":38}Bei MQTT 3.1.1 stehen replyTo, correlationId und notAfter in der Payload. Kafka nutzt <topic>.write und <topic>.write-results (geplant M3).
Node-RED Grundgerüst umgesetzt
Paket @autexis/node-red-contrib-autexis-pdc-edge für Node.js ≥ 20 und Node-RED ≥ 4.0. Alle Nodes einer Edge teilen eine WebSocket-Verbindung mit Reconnect und Versionsprüfung. Die Nodes funktionieren ohne DF.
Regel: Ist eine Anlage an eine Edge angebunden, liest und schreibt Node-RED nur noch über diese Nodes – keine direkten S7-, OPC-UA- oder Modbus-Nodes auf dieselbe Steuerung.
Vollständiger Umfang und Aufnahme ins Gateway-Basis-Image: geplant (M2)
| Node | Zweck |
|---|---|
PDC Edge Config | Verbindung, API-Token, TLS; Defaults aus PDC_EDGE_URL, PDC_EDGE_API_KEY, PDC_EDGE_CA_PATH |
PDC Edge In | Signale bzw. UNS-Pfade abonnieren |
PDC Edge Get | Einmal lesen, aus dem Cache oder vom Gerät |
PDC Edge Write | Schreiben mit Quittung; Ausgang 1 Erfolg, Ausgang 2 Fehler |
PDC Edge Event | Ereignisse der Edge, ersetzt DF4 PDC Health Check |
Verarbeitung mit JavaScript umgesetzt
Ausdrücke und Scripts laufen in einer QuickJS-Sandbox ohne Dateisystem-, Netzwerk- und Prozesszugriff, mit Zeit- und Speicherlimit. Ein Ausdruck (expr) ist ein einzelner JS-Ausdruck, ein Script (source) ein Funktionsrumpf mit return. Testen ohne Aktivierung: POST /api/v1/scripts/test (Dry-Run, auch als Dialog im UI).
| Global | Bedeutung |
|---|---|
value, quality | Aktueller Wert und Qualität am Eingang |
prev(n) | n-ter Vorwert; braucht history.depth ≥ n |
state | Zustand pro Signal (nur script), optional persistent |
signal(ref) | Wert eines anderen Signals per ID oder uns:-Pfad, Literal |
log.debug(…) | Log im Signal-Health und im Dry-Run |
signals:
- id: sim-script
group: sim-process
address: "counter:step=1"
dataType: uint32
access: read
history: { depth: 2 }
uns: { name: script-demo }
processing:
- type: expression
expr: "value * 10"
- type: script
outputType: json
timeout: 20ms
source: |
state.calls = (state.calls ?? 0) + 1;
log.debug("value", value, "prev", prev(1));
return { v: value, prev: prev(1), calls: state.calls, even: value % 20 === 0 };
triggers:
- id: sim-started
on: { signal: sim-running, edge: rising }
payload: { strokes: 'signal("sim-strokes")' }
publish: trueKonfiguration als YAML
Das Beispiel ist lauffähig gegen den Simulator. Es zeigt Metadaten, Namespace, ein Gerät und ein beschreibbares Signal, dessen Rohwert die Edge beim Schreiben über die Skalierung zurückrechnet.
cargo run -p pdc-edge -- validate examples/simulator.yaml
cargo run -p pdc-edge -- run --config examples/simulator.yaml --auth dev --data-dir ./data
curl -s localhost:8080/api/v1/signals/sim-temp/value--auth dev schaltet die Authentisierung ab und ist nur für die Entwicklung gedacht. JSON-Schema der Konfiguration: pdc-edge schema.
apiVersion: pdc.autexis.ch/v1
kind: EdgeConfig
metadata:
instanceId: edge-sim-demo
name: "Simulator Demo"
configOwner: local
namespace:
prefix: ""
source: local
nodes:
- { id: acme, slug: acme, level: enterprise }
- { id: werk1, slug: werk1, level: site, parent: acme }
- { id: demo-line, slug: demo-line, level: line, parent: werk1 }
- { id: sim-press, slug: sim-press, level: workCell, parent: demo-line }
devices:
- id: sim1
name: "Simulator 1"
driver: sim
settings: { seed: 42 }
acquisition: { mode: poll, interval: 100ms }
writePolicy: { allowWrites: true }
groups:
- id: sim-process
name: "Simulator / Prozess"
defaults: { device: sim1, node: sim-press, labels: { category: process } }
signals:
- id: sim-setpoint
group: sim-process
address: "memory:initial=0"
dataType: float64
access: readWrite
uns: { name: setpoint-speed }
processing:
- { type: scale, mode: linear, factor: 0.1, offset: 0 }
write: { enabled: true, min: 0, max: 120, timeout: 3s }