Zum Hauptinhalt springen

API-Integrationsleitfaden

So rufen externe Systeme die MCP- und API-Schnittstellen von PlantPulse AI direkt auf.

Stochern Sie nicht nach verschwundenen Adressen

Die alten eigenständigen Dienste MCP Server(:50000) · Ontology(:8888) wurden archiviert, und :7114, das LightRAG direkt öffnete, gibt es ebenfalls nicht mehr. Die Werkzeuge sind unter einer einzigen Adresse, dem MCP Gateway, gebündelt → Karte der MCP-Werkzeuge


MCP-Clients verbinden sich über die eine Gateway-Adresse​

Externe MCP-Clients (andere Agenten · Desktop-Apps usw.) verbinden sich über eine einzige Adresse, https://<호스트>/mcp/gateway/ (Streamable HTTP). Die Werkzeuge des integrierten Platform-MCP · der Zeitreihen-Insights · von RAG · Dokumentenverständnis · Vision · Engineering-Berechnung · Digital Thread · der vom Betreiber angebundenen externen Server sind unter dieser Adresse gebündelt.

AufgabeOrt
Schlüssel erhaltenIssue a key unter AI-Administrationskonsole › MCP Gateway › Client API Keys — der Schlüssel (ppgw_…) ist direkt nach der Ausstellung nur einmal sichtbar. Geben Sie dem Schlüssel einen Umfang (Anlage · Standort · Projekt · Kunden-PO · Lieferant) und eine Stufe — ein Schlüssel ohne Umfang ruft nur Werkzeuge externer Server auf
Sichtbare Werkzeuge festlegenPermissions im selben Menü — ein neuer Schlüssel beginnt ohne jede Freigabe. Je Server geben Sie «All tools» oder einzelne Werkzeuge frei
AufrufenX-API-Key: ppgw_… oder Authorization: Bearer ppgw_…
Aufrufe ansehenMonitoring › Calls & Metrics — Aufrufe werden je Schlüssel protokolliert
  • Fehlt der Schlüssel oder ist er falsch, gibt es 401; ein Client, der sich in einer Minute mehr als 20-mal irrt, erhält für den Rest dieser Minute 429.
  • Dieser Pfad leitet nur das MCP des Gateways (/mcp/) weiter. Die Verwaltungs-REST-API des Gateways (/api/v1) ist von außen nicht erreichbar.
  • /mcp/gateway ohne abschließenden Schrägstrich wird auf /mcp/gateway/ umgeleitet (308).
  • Bildschirme · Berechtigungen · Widerruf von Schlüsseln → AI-Administrationskonsole — MCP Gateway

Weitere Endpunkte​

DienstURLProtokollAuthentifizierung
MCP Gatewayhttps://<호스트>/mcp/gateway/MCP (Streamable HTTP)Gateway-Schlüssel ppgw_… — oben
Öffentliche Copilot-APIhttps://<호스트>/api/v1/…RESTX-API-Key → unten
LiteLLM (Modell)http://<server>:4000OpenAI-kompatibelMaster-Key
Integriertes MCP (Platform)<platform>/api/v5/mcpMCP (JSON-RPC 2.0)api_key — Authorization: Bearer oder X-API-Key

Direkter Dienstzugriff — für Betreiber · Systemanbindung​

Die internen MCP-Server sind auch direkt erreichbar, ohne über das Gateway zu gehen. Die Authentifizierung erfolgt dabei jedoch über einen einzigen installationsweiten Inbound-Schlüssel (PI_INBOUND_API_KEY), wer ihn hält, hat also volle Rechte, und es gibt weder Werkzeugberechtigungen pro Aufrufer noch ein Aufrufprotokoll. Nutzen Sie ihn nur für Systemanbindungen wie Betreiberskripte · Platform-CEP, und geben Sie den MCP-Clients der Kunden das Gateway.

DienstDirekte AdresseAuthentifizierung
Zeitreihen-Insightshttp://<server>:8970/mcp/ · https://<호스트>/mcp/timeseries/Inbound-Schlüssel
RAG-Gatewayhttp://<server>:7115/mcp/ · https://<호스트>/mcp/rag/Inbound-Schlüssel
Dokumentenverständnishttps://<호스트>/mcp/parser/ (Host-Port 7120 ist nicht veröffentlicht)Inbound-Schlüssel
Visionhttps://<호스트>/mcp/vision/ (Host-Port 7130 ist nicht veröffentlicht)Inbound-Schlüssel

Digital Thread · Engineering-Berechnung · das integrierte Platform-MCP erreichen Sie unter einer einzigen Adresse nur über das Gateway.

Auch über Pfade am Standard-Host erreichbar​

Auch ohne eigene Subdomain oder Port leitet der Proxy über Pfade am Standard-Host (dieselbe Adresse wie der Chat) Folgendes weiter:

PfadWohin weitergeleitet wird
https://<호스트>/mcp/gateway/MCP des MCP Gateway — für externe MCP-Clients
https://<호스트>/llm/LiteLLM — die base_url des OpenAI-SDK ist https://<호스트>/llm/v1
https://<호스트>/mcp/rag/MCP des RAG-Gateways
https://<호스트>/mcp/timeseries/MCP der Zeitreihen-Insights
https://<호스트>/mcp/parser/MCP des Dokumentenverständnisses
https://<호스트>/mcp/vision/MCP der Vision
Diese Pfade öffnet der Proxy nicht ohne Weiteres

Die Authentifizierung übernimmt das Backend — /mcp/gateway/ verlangt den Gateway-Schlüssel ppgw_…, das direkte MCP-Netz X-API-Key: <PI_INBOUND_API_KEY>, und /llm/ antwortet mit 401 ohne den LiteLLM-Master-Key. Der Standard-Host ist meist eine Adresse mit externem DNS, prüfen Sie daher nach der Installation unbedingt mit CHANGE_ME_…, ob kein Key übrig geblieben ist → Zugangsdaten-Verwaltung

Die LiteLLM-Admin-Oberfläche (/llm/ui) wird über diesen Pfad nicht geöffnet — öffnen Sie sie über :4000.

Eingehende Schlüssel im Backend​

Zeitreihen-Insights · RAG · Dokumentenverständnis · Vision · Digital Thread verwenden denselben eingehenden Schlüssel (PI_INBOUND_API_KEY in der Installations-env) → Zugangsdaten-Verwaltung. Gesendet wird er als X-API-Key: <key> oder Authorization: Bearer <key>.

  • Ohne Schlüssel erreichbar sind nur /ping · /health. /metrics benötigt ebenfalls einen Schlüssel.

  • Fehlt der Schlüssel oder ist er falsch, kommt 401 (bei RAG missing or invalid API key).

  • 🔴 Ist der Schlüssel leer, startet der Dienst nicht (fail-closed). Die Installationsprüfung (bin/lint-env.sh) bleibt zuerst bei [fail] PI_INBOUND_API_KEY is empty and PI_INBOUND_AUTH_DISABLED is not true stehen, und im Dienst-Log erscheint FATAL: … is empty — refusing to start …. Ein «still offenes Backend» mit leerem Schlüssel gibt es nicht.

  • Um die Authentifizierung absichtlich auszuschalten (z. B. isolierte Testumgebung), tragen Sie PI_INBOUND_AUTH_DISABLED=true in die Installations-env ein (Standard false). Compose reicht diesen Wert unter dienstspezifischen Namen durch.

    DienstName, den der Container liest
    RAGRAG_INBOUND_AUTH_DISABLED
    Zeitreihen-InsightsTS_INBOUND_AUTH_DISABLED
    Digital ThreadDT_INBOUND_AUTH_DISABLED
    Dokumentenverständnis · VisionINBOUND_AUTH_DISABLED

    Ist ein Schlüssel gesetzt, gewinnt der Schlüssel (lint-env meldet dies mit [note] … is ignored — PI_INBOUND_API_KEY is set and the key wins). Werte außerhalb von true · false sind [fail]. Dienste, die ohne Authentifizierung laufen, vermerken dies in /health (Digital Thread auth.inbound=disabled, Zeitreihen-Insights inbound_auth: "disabled") — über die Schaltfläche Prüfung ausführen im Bildschirm API-Schlüssel der Admin-Konsole wird dies als offen erkannt → AI-Admin-Konsole — API-Schlüssel

Dokumentenverständnis und Vision veröffentlichen keine Host-Ports (7120 · 7130) — von außen sind sie nur über die oben genannten Pfade /mcp/parser/ · /mcp/vision/ erreichbar. Auch Digital Thread (7140) öffnet keinen Host-Port.

Der MCP-Pfad schließt den abschließenden Schrägstrich ein

Es heißt nicht /mcp, sondern /mcp/. Lässt man den Schrägstrich weg, kommt es zu einer Weiterleitung oder einem 404.


MCP-Protokollaufruf​

Alle fünf Server folgen dem MCP(Model Context Protocol)-Standard. Werkzeuge für Fabrikdaten und Ontologie liegen im integrierten Platform-MCP (/api/v5/mcp), Signalanalyse bei den Zeitreihen-Insights, Dokumente und Fotos bei den übrigen drei.

Präfixe vor Werkzeugnamen gibt es nur im Chat

Beim direkten Aufruf des Servers verwenden Sie den Namen ohne Präfix (analyze_asset). Präfixe wie insight_ werden von der Werkzeug-Registrierung des Chats hinzugefügt — der Name im Chat-Bildschirm unterscheidet sich daher vom hier verwendeten Namen.

MCP-Grundstruktur​

MCP ist HTTP-POST-Kommunikation auf Basis von JSON-RPC 2.0. Das integrierte MCP benötigt api_key-Authentifizierung (Authorization: Bearer <token>).

POST /api/v5/mcp HTTP/1.1
Content-Type: application/json
Authorization: Bearer <platform.api.token>

{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "<tool-name>",
"arguments": {
"<param1>": "<value1>",
"<param2>": "<value2>"
}
}
}

Abruf der Werkzeugliste​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'

Beispiel eines Werkzeugaufrufs​

Fast immer beginnt es mit search_domains

Menschen sprechen mit Namen, Werkzeuge erhalten IDs. Der Standardablauf ist, dass search_domains 14 Domänen per Teiltreffer durchsucht, um «Domäne + ID» festzulegen, und diese ID dann an das Detail-Werkzeug übergibt.

① Per Name suchen, um die ID zu erhalten​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_domains",
"arguments": {
"query": "압축기",
"domain": "asset",
"limit": 20
}
}
}'

Kennt man domain, kann man gezielt danach suchen; lässt man es weg, wird nach Domänen getrennt zurückgegeben.

② Die Anlagenhierarchie aufklappen​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_asset_tree",
"arguments": { "asset_id": "<①에서 얻은 ID>" }
}
}'
Das Fehlen des Schlüssels tags bedeutet nicht «keine Tags»

Standardmäßig wird nur die Anzahl (tag_count) der Tags geliefert. Geben Sie include_tags: true nur an, wenn Sie Name · tag_id tatsächlich benötigen — die Antwort wird dann um ein Vielfaches größer. Maßgeblich dafür, ob Tags vorhanden sind, ist tag_count, und nur tag_count: 0 bedeutet wirklich keine Tags.

③ Aktuelle Tag-Werte auf einen Schlag lesen​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_tag_values",
"arguments": { "tag_ids": ["<tag_id>", "<tag_id>"] }
}
}'

tag_ids ist ein Array und erlaubt bis zu 100 auf einmal. In der Antwort bedeutet found: false ein nicht registriertes Tag, error einen fehlgeschlagenen Abruf (ein erneuter Versuch lohnt sich). Für Verlaufsdaten über einen Zeitraum verwenden Sie get_tag_history.


Integrierte MCP-Authentifizierung​

Das integrierte MCP erfordert zwingend api_key-Authentifizierung. Der vom Chat verwendete Wert ist platform.api.url · platform.api.token des Copiloten (Umgebungsvariablen CO_PLATFORM_API_URL · CO_PLATFORM_API_TOKEN — Compose überträgt PP_API_URL · PP_API_TOKEN aus der Host-env). Das bis 2026.09 verwendete Präfix CH_ wurde in 2026.10 zu CO_ geändert, ohne Fallback.

⚠ Die alten Namen mcp.api.url · mcp.api.token gibt es nicht mehr. Beim Hochfahren werden alte Konfigurationszeilen auf die neuen Namen umgestellt, aber wird die Umgebungsvariable unter dem alten Namen gesetzt, geschieht nichts.

Authentifizierungs-Header​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{ ... }'

Ontologie(Wissensgraph)-Aufruf​

Die Ontologie-Werkzeuge wurden in das integrierte MCP aufgenommen. 🔴 Ein Werkzeug namens ontology_* gibt es nicht — das ist der Name aus der Zeit des alten eigenständigen Dienstes (:8888). Heute gibt es drei.

WerkzeugWorauf es antwortet
get_ontologyKonfigurationsüberblick einer Site — Zonen-/Linien-/Anlagenstruktur + Tag-Anzahl je Anlage
query_ontologySuche nach gerichteten Beziehungen — „Was beeinflusst X“, stromauf·stromab
query_sparqlMehrfach-Bedingungs-Kreuzabfrage (nur SELECT / ASK)

Die Namen ähneln sich, liefern aber unterschiedliche Achsen zurück. Die reine Hierarchiestruktur liefert get_asset_tree, den Konfigurationsüberblick der Site liefert get_ontology, die Beziehungsausbreitung liefert query_ontology.

Konfigurationsüberblick der Site​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_ontology",
"arguments": { "site_id": "<site_id>" }
}
}'

site_id ist Pflicht — lösen Sie ihn zuerst über search_domains mit domain: "site" auf.

Maßgeblich für die Gesamtzahl der Tags ist allein total_tag_count

Summieren Sie nicht die tag_count je Knoten — nicht aufgeklappte Zweige fehlen dann. total_tag_count_unknown: true bedeutet „konnte nicht gezählt werden“, schätzen Sie es daher nicht.

Beziehungssuche — „Was beeinflusst dies“​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "query_ontology",
"arguments": {
"entity_id": "<설비 ID>",
"direction": "DOWN",
"depth": 2
}
}
}'
ParameterWertBedeutung
entity_id(Pflicht)Entität, bei der die Suche beginnt
relation_typeFEEDS · DEPENDS_ON · PRODUCESBei Weglassen alle
directionUP · DOWN · BOTHStandard DOWN (stromabwärtige Wirkung)
depth1 ~ 5Standard 2

Die Antwort besteht aus root + nodes[] + edges[] + truncated. truncated: true bedeutet, dass bei Tiefe oder Breite abgeschnitten wurde — fragen Sie mit engerem Bereich erneut.


MCP-Aufruf der Zeitreihen-Insights​

Anomalieerkennung der Anlage​

curl -X POST http://127.0.0.1:8970/mcp/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "detect_asset_anomaly",
"arguments": {
"asset_id": "ASSET_DJ_M_01_1",
"lookback_minutes": 1440,
"top_k": 5
}
}
}'

Lässt man threshold weg, gilt standardmäßig 5.0. Der Sensor-Anomalie-Score liegt nicht zwischen 0 und 1, sondern ist ein kalibrierter Score (robuster Z-Wert gegenüber dem Referenzzeitraum) — mit 0 wird daher schon ein geringfügiges Abweichen vom Referenzmedian als Anomalie gezählt → AI-Modelle

Sensorprognose der Anlage​

curl -X POST http://127.0.0.1:8970/mcp/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "forecast_asset",
"arguments": {
"asset_id": "ASSET_DJ_M_01_1",
"prediction_length": 96,
"enable_bounds": true
}
}
}'

Health-Score der Anlage​

curl -X POST http://127.0.0.1:8970/mcp/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_asset_health",
"arguments": {
"asset_id": "ASSET_DJ_M_01_1"
}
}
}'

RAG (LightRAG)-Aufruf​

Die RAG-Engine ist LightRAG 1.5.7 (ab 2026.10 in unserem gewrappten Image pi/plantpulse-lightrag), aber 🔴 sie wird nicht direkt aufgerufen. LightRAG existiert nur innerhalb des Containers; von außen erreichbar ist einzig das rag-api(7115)-Gateway.

Dokumente hochladen, auflisten und löschen erfolgt über die Admin-Konsole (das alte LightRAG-WebUI wurde in die Konsole integriert). Die Suche wird über das REST des Gateways aufgerufen und mit X-API-Key authentifiziert.

info

Die Dokumentensuche im Copilot-Chat ruft das MCP-Tool rag_search dieses Gateways über das MCP Gateway auf (eine eingebaute Dokumentensuche hat der Copilot nicht). REST /api/v1/query und MCP rag_search liefern denselben Umschlag — nicht direkt gegen LightRAG. Die unten gezeigte Antwortform stammt nicht von LightRAG, sondern ist der vom Gateway definierte Umschlag.

Textsuche​

curl -X POST http://127.0.0.1:7115/api/v1/query \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"query": "펌프 정비 절차",
"mode": "hybrid"
}'
ParameterWert
querySuchbegriff — mindestens 3 Zeichen (kürzer ergibt 400)
modehybrid (Standard) · naive · local · global — andere Werte ergeben 422
AntwortBedeutung
{"retrieved": true, "answer": …, "sources": [{"file_name": …, "reference_id": …}]}Gefunden. reference_id ist das n aus der Quellenmarkierung [n] im Antworttext (fehlt bei
Quellen ohne Nummerierung durch die Engine)
{"retrieved": false, "code": …, "reason": …, "sources": []}Nicht gefunden. Der Schlüssel answer fehlt gänzlich
HTTP 502Fehler auf Engine-Seite
retrieved: false ist kein Fehler, sondern „nicht vorhanden“

Der HTTP-Status ist 200. Ist code gleich NO_CONTEXT, enthalten die indizierten Dokumente keine relevanten Inhalte; ist es EMPTY_ANSWER, ist die Engine leer zurückgekommen. Ein erneuter Aufruf liefert dieselbe Antwort — zeigen Sie eine Antwort ohne answer nicht als Ergebnis an.


Zeichnungsvergleich — Unterschiede zwischen zwei Revisionen​

Dies ist nur in Installationen verfügbar, bei denen die Zeichnungserfassung (DRAWING_INGEST_ENABLED=true) aktiviert ist → Umgebungsvariablen konfigurieren. Es gibt zwei Eingänge, und der Vergleich selbst erfolgt im Dokumentenverständnis. rag-api holt die Originale beider indizierter Revisionen heraus, reicht sie an das Dokumentenverständnis weiter und gibt dessen Ergebnis unverändert zurück. Beide erfordern den eingehenden Schlüssel.

EingangWann
rag-api GET /api/v1/drawings/{asset_id}/{doc_name}/diffBereits indizierte Zeichnungen — findet die vorherige Revision und vergleicht
Dokumentenverständnis POST /api/v1/drawings/diffVergleicht direkt zwei vorliegende Dateien (unabhängig von der Indizierung)

Vergleich mit der vorherigen Revision einer indizierten Zeichnung (rag-api)​

curl -G "http://127.0.0.1:7115/api/v1/drawings/<asset_id>/<doc_name>/diff" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
--data-urlencode "lang=ko"
ParameterBedeutung
againstDokumentname der zu vergleichenden vorherigen Revision. Leer gelassen, wird unter
derselben Zeichnungsnummer die Revision mit der unmittelbar vorangehenden Revisionsmarkierung
gewählt (A < B < … < Z < AA, 1 < 2 < 10)
against_assetAnlagen-ID, falls die vorherige Revision bei einer anderen Anlage hinterlegt ist
(Standard: dieselbe Anlage)
langSprache der summary-Zeile ko · en. Leer gelassen die Installationssprache
(PP_LANG). Zahlen bleiben unabhängig von der Sprache exakt wie in der Zeichnung angegeben
StatusBedeutung
404Eine Seite ist nicht indiziert, das Original nicht archiviert, oder es gibt keine
auswählbare vorherige Revision
422Der Vergleicher kann die Datei nicht lesen
502Vergleicher oder Objektspeicher nicht erreichbar

Im selben Router gibt es Seitenvorschauen (…/page/{n} — PDF als PNG, DXF als SVG) und Revisionsstatus (…/revision-status — current · outdated · change_open · unknown).

Zwei vorliegende Dateien direkt vergleichen (Dokumentenverständnis)​

Da das Dokumentenverständnis keinen Host-Port veröffentlicht, wird von außen der Standard-Host unter parser.* aufgerufen.

curl -X POST "https://parser.<domain>/api/v1/drawings/diff" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-F "old=@A-100_rev-A.dxf" -F "new=@A-100_rev-B.dxf" -F "lang=ko"
  • Dateien müssen .dxf oder Vektor-.pdf mit Textebene sein, maximal 50 MB je Datei. DWG wird nicht angenommen.
  • Der Standardwert für lang ist en (abweichend vom rag-api-Eingang).
  • Ablehnungen kommen mit error_kind: input bei falscher Erweiterung 415 · zu großer Größe 413 · nicht lesbar 400.

Form des Ergebnisses​

SchlüsselEnthält
titleGeänderte Felder im Titelblock
dimensionsadded · removed · changed (was sich geändert hat: Wert · Einheit · Anzahl · Toleranz ·
Text · Position) · unchanged
bom · notesGeänderte BOM-Zeilen · Stückliste
regionsGeänderte Bereiche — bbox der neuen Revision und bbox_old der vorherigen. Schlägt die
Zuordnung fehl, kommen status: unavailable und der Grund — Bereiche werden nicht erfunden
summaryFür Menschen lesbare Zusammenfassungszeile — Zahlen exakt wie in der Zeichnung
confidence · limitshigh · medium · low sowie nicht Vergleichbares (gescannte Seite ·
kein Titelblock · BOM nur auf einer Seite usw.)
warningsdifferent_drawing_numbers (unterschiedliche Zeichnungsnummer) · revision_label_unchanged (gleiche Revisionsmarkierung) usw.

Video · Audio — /api/v1/media von rag-api​

Dieser Pfad existiert nur bei Installationen mit aktivierter Video-/Audio-Erfassung (Installations-env PI_MEDIA_ENABLED=true). In deaktivierten Installationen fehlt der Pfad komplett — 404, und Video-/Audio-Uploads werden mit 400 abgelehnt. Ob er aktiviert ist, sehen Sie an media_ingest_enabled in GET /api/v1/config → Umgebungsvariablen konfigurieren · AI-Admin-Konsole — Video

Methode · PfadTätigkeit
GET /api/v1/media/jobsVerarbeitungsstatus · Dauer · Segmentanzahl · Anzahl Szenenbilder (thumb_count) und
Verarbeitungszeitraum (window — open · next_start · spec) pro Datei
GET /api/v1/media/jobs/{asset_id}/{doc_name}Detail einer einzelnen Datei
GET /api/v1/media/integrityIndizierte, aber nicht im Suchindex enthaltene Segmente
POST /api/v1/media/jobs/{asset_id}/{doc_name}/retryErneut in die Warteschlange (fehlgeschlagen · übersprungen). Mit ?force=true komplette
Neutranskription
GET /api/v1/media/{asset_id}/{doc_name}/transcriptArchiviertes Transkript
GET /api/v1/media/{asset_id}/{doc_name}/thumb?t=<ms>Nächstgelegenes Szenenbild vor diesem Zeitpunkt
GET /api/v1/media/{asset_id}/{doc_name}/streamWiedergabe — antwortet auf Range-Anfragen mit 206
  • Hochladen erfolgt über dieselbe POST /api/v1/docs/upload wie bei Dokumenten, Löschen ebenfalls über dieselbe DELETE /api/v1/docs/{asset_id}/{doc_name} (Inhalte aus dem Platform-Register sind 409).
  • Szenenbilder (…/thumb) fügen ETag und Cache-Control: private, max-age=86400 an. Wird dieselbe ETag als If-None-Match gesendet, antwortet das System ohne erneutes Lesen des Bildes mit 304. Ist die Status-Datenbank kurzzeitig ausgelastet, kommt statt 500 503 mit state database busy, retry shortly und Retry-After: 1 — rufen Sie nach dieser Zeit erneut auf.
  • Auch die vom Copilot-Bildschirm genutzte Relaisroute (/media/thumb · /media/stream des Copiloten, Authentifizierung über Login-Sitzung) gibt ETag · 304 unverändert weiter, und das 503 des Backends wird mit Retry-After als 503 weitergegeben (früher wurde es als 502 verpackt).

Anfrage-ID und Metriken — X-Request-ID · /metrics​

Seit dem Re-Release 2026.10 verwenden die fünf Python-Backends (RAG · Zeitreihen-Insights-API · Dokumentenverständnis · Vision · Digital Thread) dieselbe Regel.

  • Anfrage-ID — Senden Sie X-Request-ID (1–128 Zeichen, Buchstaben · Ziffern · . _ -) mit der Anfrage, wird dieser Wert zurückgegeben; fehlt er oder hat falsche Form, wird ein neu erzeugter Wert im Antwort-Header X-Request-ID zurückgegeben. Während die Anfrage läuft, wird derselbe Wert als request_id an die Log-Zeilen angehängt. RAG fügt request_id auch dem Fehler-Antworttext hinzu.
  • Metriken — GET /metrics liefert das Prometheus-Textformat. Ein eingehender Schlüssel ist erforderlich (im Gegensatz zum Health-Pfad keine Ausnahme). Der Port hat sich nicht geändert → Protokollierung und Monitoring
curl -s -D - -o /dev/null -H "X-Request-ID: my-trace-001" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" http://127.0.0.1:7115/api/v1/config | grep -i x-request-id

LLM-API-Aufruf (OpenAI-kompatibel)​

Der LiteLLM-Proxy bietet eine OpenAI-kompatible API. Das vorhandene OpenAI-SDK kann unverändert verwendet werden. Im LAN gilt http://<server>:4000/v1, über den Standard-Host https://<호스트>/llm/v1.

Chat Completion​

curl http://127.0.0.1:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 설치-시-변경" \
-d '{
"model": "aura-lite",
"messages": [
{"role": "user", "content": "주입기 베어링 교체 주기를 알려줘."}
],
"temperature": 0.7
}'

Embedding-Erzeugung​

curl http://127.0.0.1:4000/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 설치-시-변경" \
-d '{
"model": "aura-embedding-4b",
"input": "주입기 베어링 교체 절차"
}'

Modellliste abrufen​

curl http://127.0.0.1:4000/v1/models \
-H "Authorization: Bearer 설치-시-변경"

Verfügbare Modelle​

ModellnameVerwendungszweckTatsächliches Modell
aura-liteDialog · Analyse (auch mit Bildeingabe)Aura — Standard Aura-Lite-NVFP4
aura-visionVision-Alias derselben Engine wie obendasselbe Modell wie oben
aura-embedding-4bEmbeddingAura-Embedding-4B
aura-reranker-0.6bRerankingAura-Reranker-0.6B
Die alten Namen gpt-4o · text-embedding-3-large sind jetzt ein Fehler

Frühere Versionen akzeptierten OpenAI-kompatible Aliase (gpt-4o · gpt-4o-mini · text-embedding-3-large · rerank-multilingual-v3.0). Jetzt werden sie nicht mehr akzeptiert — bleibt der alte Name im Integrationscode, wird der Aufruf abgelehnt. Ersetzen Sie ihn durch den Namen aus der obigen Tabelle. Welche Namen aktuell verfügbar sind, können Sie mit /v1/models prüfen.

Unabhängig vom Namen geht die Anfrage an das intern laufende Aura-Modell — auch bei Air-Gap-Netzwerk-Installationen gleich.


Python-SDK-Beispiele​

LLM-Aufruf mit dem OpenAI-SDK​

from openai import OpenAI

client = OpenAI(
base_url="http://127.0.0.1:4000/v1",
api_key="설치-시-변경"
)

response = client.chat.completions.create(
model="aura-lite",
messages=[
{"role": "user", "content": "주입기 상태를 분석해줘."}
]
)

print(response.choices[0].message.content)

MCP-Werkzeugaufruf​

import requests

def call_mcp_tool(url, tool_name, arguments=None, headers=None):
response = requests.post(
url,
headers=headers or {},
json={
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": tool_name,
"arguments": arguments or {}
}
}
)
return response.json()

# 이름으로 설비를 찾는다 (통합 MCP — api_key 필요)
result = call_mcp_tool(
"<platform>/api/v5/mcp",
"search_domains",
{"query": "압축기", "domain": "asset"},
headers={"Authorization": "Bearer <platform.api.token>"}
)
print(result)

# 설비 이상 탐지 (TimeSeries-Insight — 인바운드 키 필요)
result = call_mcp_tool(
"http://127.0.0.1:8970/mcp/",
"detect_asset_anomaly",
{"asset_id": "ASSET_DJ_M_01_1", "lookback_minutes": 1440},
headers={"X-API-Key": "<PI_INBOUND_API_KEY>"}
)
print(result)

Öffentliche Copilot-API (/api/v1)​

Ein Eingang für externe Systeme, um Chat und Morgenkarten unverändert zu nutzen. Er liegt an derselben Adresse wie der Chat (Standard-Host).

Methode · PfadTätigkeit
POST /api/v1/chatFragen stellen und Antworten erhalten. Welche Werkzeuge benötigt werden, wählt der Server
GET /api/v1/tasks/dailyLiest die tägliche Karte des Tages (erzeugt jeden Tag um 05:00) ein. ?date=YYYY-MM-DD — bezogen
auf die Zeitzone des Werks, leer gelassen heute
GET /api/v1/toolsListe der Werkzeuge, die der Agent gerade jetzt verwenden kann (Name · Beschreibung ·
nur lesend oder nicht)
GET /api/v1/ai-feedbackLiest sowohl von Menschen an AI-Ergebnissen vergebene Markierungen (Fehlalarm ·
Vorschlag angenommen/abgelehnt/Wirkung) als auch vom Server regelbasiert vergebene Markierungen
(richtig · Fehlalarm · verpasst) — 2026.10 (siehe unten)
curl -X POST https://<호스트>/api/v1/chat \
-H "Content-Type: application/json" \
-H "X-API-Key: <발급받은 키>" \
-d '{ "input_value": "지금 끊어진 엣지 장비가 몇 대야?" }'

Die Antwort besteht aus answer (Markdown) · session_id · duration_ms · tools (Werkzeuge, die zur Erstellung dieser Antwort aufgerufen wurden). Lässt man session_id weg oder leer, wird eine neue Unterhaltung geöffnet (entspricht „Neue Unterhaltung“ im Bildschirm — Standard-App, Eigentum des Aufrufers), und deren ID wird als session_id in der Antwort zurückgegeben. Um die Unterhaltung fortzusetzen, geben Sie diesen Wert in der nächsten Anfrage an. Da es sich um einen synchronen Aufruf handelt, können Fragen mit mehreren Werkzeugaufrufen mehrere Dutzend Sekunden dauern.

In der Version 2026.09 führte ein Aufruf ohne session_id zu 500

Die Dokumentation besagte „leer bedeutet neue Unterhaltung“, aber der Server gab 500 zurück, und auch Aufrufe mit X-API-Key endeten mit 500. In 2026.10 wurden beide Fälle behoben.

Eine leere Antwort ergibt 502

Ab Re-Release 3 von 2026.10 wird HTTP 502 zurückgegeben, wenn das Modell auch nach erneutem Versuch keine Antwort erzeugen kann. Die Form des Antworttexts bleibt gleich, answer ist leer. Damit wird vermieden, dass eine leere Antwort mit 200 als Ergebnis angezeigt wird — senden Sie dieselbe Frage einfach erneut.

Von Menschen an AI-Ergebnissen vergebene Markierungen — GET /api/v1/ai-feedback​

Ein Eingang, der ausschließlich lesend die von Menschen bei Vorschlägen des Copiloten vergebenen Markierungen (Ablehnungsgrund · angenommen/abgelehnt · Wirkung) liefert (schreibbar ist dies nur über den Bildschirm) → AI-Befunde und Genauigkeit — vom Menschen hinterlassene Beurteilung. Die Authentifizierung entspricht den übrigen /api/v1 (nur X-API-Key — ab Re-Release 6 von 2026.10 ergibt eine Login-Sitzung 403).

curl "https://<호스트>/api/v1/ai-feedback?since=2026-10-01T00:00:00Z&limit=500" \
-H "X-API-Key: <발급받은 키>"
ParameterBedeutung
sinceUntergrenze von labeled_at (RFC 3339 oder Epoch-ms). Leer gelassen von Anfang an
asset_idFiltert nach Anlagen-ID
target_kindANOMALY (eine Anomalie) · FINDING (AI-Befund) · PROPOSAL (aus Befund entstandene
Vorschlagskarte) · MISSED (gemeldete verpasste Anomalie) · DAILY_TASK
limitMaximale Zeilenanzahl 1–1000, Standard 500

Die Antwort besteht aus count · items · next_since. Da von alt nach neu geliefert wird, rufen Sie die nächste Seite mit next_since erneut auf — da Zeilen mit demselben Zeitpunkt überlappen können, filtern Sie nach feedback_id. Drückt der Mensch beim selben Ziel erneut, ändern sich value · labeled_at dieser Zeile (die letzte Markierung gewinnt).

label_keyvalue
verdicthit · false_alarm · unsure (Beurteilung zurückgestellt — aus der Genauigkeitsberechnung
ausgeschlossen)
reasonGründe für Fehlalarm setup · idle · maintenance · sensor · other / Gründe für
Ablehnung des Vorschlags already_done · not_needed · wrong · other
causeTatsächliche Ursache breakdown · degradation · sensor · setup · maintenance · normal · other
proposal_decisionaccepted · rejected
outcomeeffective · not_effective · unknown (Notiz in comment)
missedmissed (Erklärung in comment, Zeitpunkt des verpassten Ereignisses in occurred_at)

Im neuen Bildschirm (Drei-Menü-Set) sind die von Menschen hinterlassenen Werte false_alarm von verdict (Ignorieren der zu prüfenden Anomalie) sowie deren reason, proposal_decision, outcome. hit · missed werden durch den Abgleich der Stillstand-/Störungsregeln des Servers vergeben, unsure · cause stehen in Zeilen aus dem alten Bildschirm.

Jede Zeile enthält zudem occurred_at (Ereigniszeitpunkt, auf den die Markierung sich bezieht) · labeled_by · labeled_at · config_ver (Beurteilungsversion, die zu diesem Ergebnis führte), und …Stamp neben dem Zeitpunkt ist der in der Zeitzone des Werks (PP_TZ) angegebene Wert.

Schlüssel — zwei Methoden​

MethodeWoEigenschaft
Ausgestellter Schlüssel (empfohlen)Copilot-Admin-Konsole
→ API-Schlüssel → AusstellenMehrere benannte Schlüssel können ausgestellt und
einzeln widerrufen werden. Der letzte Verwendungszeitpunkt wird festgehalten
Umgebungsvariablen-SchlüsselCO_API_V1_KEY in /etc/kopens/plantpulse-ai.env (bis 2026.09 CH_API_V1_KEY — der alte Name wird
stillschweigend ignoriert)Nur eine einzige Zeile. **Leer gelassen wird nur die
Authentifizierung über diesen Schlüssel deaktiviert**
Ein ausgestellter Schlüssel wird «nur einmal direkt nach der Ausstellung» angezeigt

Gespeichert wird nur der Hash, daher erscheinen in der Liste nur die ersten Zeichen. Bei Verlust stellen Sie einen neuen aus und widerrufen den alten.

Über diesen Schlüssel ist nur die öffentliche API erreichbar

Der Schlüssel gewährt Zugriff auf /api/v1 und das Copilot-MCP (/mcp). Ab Re-Release 6 von 2026.10 sind diese beiden Pfade ausschließlich per Schlüssel zugänglich, ein Aufruf per eingeloggter Browsersitzung ergibt 403. Berechtigung und Dokumentenklassifizierung von per Schlüssel ausgeführten Aufrufen folgen der Rollengruppe „Externes System“ (Standard: vertraulich), der Geltungsbereich ist stets vollständig → Berechtigungen. Admin-Pfade und der API-Dokumentationsbildschirm (/swagger-ui.html) erfordern Admin-Login. Ein Weg, Werkzeuge «direkt» aufzurufen, ist nicht geöffnet — Werkzeuge, die den Zustand ändern, sind mit einem menschlichen Genehmigungsverfahren verbunden.

Geänderte APIs, die der Bildschirm nutzt (2026.10 Re-Release 3)​

Im Folgenden handelt es sich nicht um die öffentliche API, sondern um Pfade, die der Copilot-Bildschirm per Login-Sitzung aufruft. Prüfen Sie dies, falls eine Integration den Bildschirm nachahmt.

Methode · PfadÄnderung
PUT /api/employees/{아이디}/work-role🔴 Nur noch Admins (zuvor auch man selbst). Body {"workRole": "maintenance"}. Jede Änderung wird im
Audit-Log als employee.work_role:<아이디> vermerkt → Benutzerrechte und Arbeitsrollen
PUT /api/employees/{아이디}/home-roleNeuer Pfad — Präferenz für den Startbildschirm der eigenen Person. Body {"homeRole": "manager"}
(dieselben fünf Werte wie bei Arbeitsrollen). Aufrufbar durch sich selbst oder Admin. Ändert
nichts an der Genehmigungsberechtigung. Der neue Bildschirm im Drei-Menü-Set (Fragen · Vorschläge ·
Automatisierung) nutzt diesen Wert nicht, da der erste Bildschirm für jeden „Fragen“ ist — der
Pfad bleibt aber erhalten
GET /api/sop?query=…&assetId=…Neuer Parameter assetId — bei Angabe werden Quellen anderer Anlagen ausgeschlossen.
Die Antwort ist {answer, sources[], citations, truncated}, und die Antwort wird an einer Satzgrenze innerhalb von 600 Zeichen
abgeschnitten (truncated). Ist der Suchbegriff zu kurz, kommt 400; antwortet der
Dokumentensuchdienst nicht, kommt 503 + Retry-After

Antwortformate​

Erfolgreiche MCP-Antwort​

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{ ... 도구 실행 결과 JSON ... }"
}
]
}
}

Fehlerhafte MCP-Antwort​

{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32600,
"message": "Invalid request",
"data": "상세 오류 메시지"
}
}

Bei großen Mengen — limit und has_more​

🔴 page · size gibt es nicht. Die Werkzeuge des integrierten MCP begrenzen die Menge mit limit und signalisieren «es gibt mehr» über has_more in der Antwort.

{
"name": "search_domains",
"arguments": {
"query": "압축기",
"domain": "asset",
"limit": 50
}
}
WerkzeugStandardwert limitMaximalwert
search_domains50500
get_tag_history500500
get_tag_values(Array tag_ids — auf einmal)100 Stück
Wenn has_more: true auftritt

Da es keine Seitenzahl gibt, ist das Standardvorgehen, die Bedingungen einzugrenzen — geben Sie domain an, kürzen Sie den Zeitraum oder konkretisieren Sie den Suchbegriff. Es ist kein Format, bei dem dieselbe Abfrage wiederholt wird, um die nächste Seite zu erhalten.


Zeitformat​

Die Zeitparameter des integrierten MCP beziehen sich auf die lokale Serverzeit. Die Namen lauten from · to, das Format ist YYYY-MM-DDTHH:MM:SS.

{
"name": "get_tag_history",
"arguments": {
"tag_id": "<tag_id>",
"from": "2026-03-29T00:00:00",
"to": "2026-03-29T23:59:59"
}
}
Offsets und Z führen zur Ablehnung

2026-03-29T00:00:00+09:00 oder ...Z werden nicht akzeptiert. Es wird nur die lokale Zeit ohne Offset akzeptiert — welche Uhrzeit der Server aktuell führt, prüfen Sie mit get_current_time.

Auch Namen wie start_time · end_time gibt es nicht. Es sind from · to.

Felder in der Antwort mit dem Suffix _iso sind in dem für Menschen gut lesbaren KST-Format:

{
"timestamp": 1711641600000,
"timestamp_iso": "2026-03-29 09:00:00"
}