12. Order-Service
Greifen Sie über client.order() zu. Der gesamte Lebenszyklus eines Arbeitsauftrags (Work Order) von Erstellung → Start → Stopp/Fortsetzung → Abschluss wird über eine ISA-88-basierte Zustandsmaschine verwaltet.
11.1 Status des Arbeitsauftrags (ISA-88-basiert)
CREATE → WAIT ──start()──► START ──pause()──► PAUSED
│ │
│ resume()
│ │
▼ ▼
END ◄──end()──── START
│
└─ (또는) ──abort()──► ABORTED
Status (status) | Bedeutung | Transitionsmethode | ISA-95 Status (isa95_state) |
|---|---|---|---|
WAIT | Wartend (Initialzustand nach Erstellung) | Ergebnis von create() | Ready |
START | In Arbeit | start(), resume() | Running |
PAUSED | Pausiert | pause() | Held |
END | Normal abgeschlossen | end() | Completed |
ABORTED | Abnormal beendet | abort() | Aborted |
status entspricht exakt dem gespeicherten Wert und umfasst nur diese fünf Zustände. Ein Arbeitsauftrag, der vor dem Start storniert wurde, ist kein neuer Status, sondern ABORTED + abort_code=CANCELLED. Arbeitsauftragszeilen (/order·Liste·/order/query), Leistungsdokumente und plantpulse.order.*-Events ergänzen hier den ISA-95 Part 4 Status des Arbeitsauftrags isa95_state — die Zuordnung erfolgt über die obige Tabelle, und alle Pfade liefern denselben Wert.
Aufrufe, die eine nicht zulässige Zustandsänderung bewirken (z. B. erneuter Aufruf von
start()im StatusSTART), führen dazu, dass der Server eine Antwort OK +data.success=falsesendet; V5-Methoden gebenfalsezurück.
11.2 Methodenübersicht
CRUD
| Methode | Rückgabetyp | HTTP | Endpunkt |
|---|---|---|---|
create(OrderRequestV5) | OrderResponseV5 oder null | POST | /api/v5/order |
update(order_id, OrderRequestV5) | OrderResponseV5 oder null | PUT | /api/v5/order/{id} |
delete(order_id) | boolean | DELETE | /api/v5/order/{id} |
get(order_id) | OrderResponseV5 oder null | GET | /api/v5/order/{id} |
list() | List<OrderResponseV5> | GET | /api/v5/order |
exists(order_id) | boolean | GET | /api/v5/order/{id}/exists |
Lebenszyklus (Alle geben boolean zurück)
| Methode | HTTP | Endpunkt |
|---|---|---|
start(order_id) | POST | /api/v5/order/{id}/start |
end(order_id) | POST | /api/v5/order/{id}/end |
pause(order_id) | POST | /api/v5/order/{id}/pause |
resume(order_id) | POST | /api/v5/order/{id}/resume |
abort(order_id) | POST | /api/v5/order/{id}/abort |
11.3 OrderRequestV5 / OrderResponseV5
| Feld | Typ | Beschreibung |
|---|---|---|
order_id | String | Arbeitsauftrags-ID (PK) |
order_name | String | Name des Arbeitsauftrags — Pflichtfeld, darf nicht leer sein (422 order.name.required). Name des B2MML JobOrder |
description | String | Beschreibung |
site_id | String | Zugehörige Site |
asset_id | String | Zielanlage (Equipment) |
customer_id | String | Kunde (Optional) |
product_id | String | Zu produzierendes Produkt |
employee_id | String | Zuständiger Mitarbeiter (Optional) |
planned_quantity | Quantity | Geplante Menge — ISA-95 / B2MML QuantityValueType. Siehe 11.5 Menge |
time_per_unit_in_ms | long | Standardzeit pro Einheit |
planned_start_timestamp | long | Geplanter Startzeitpunkt (Millisekunden) |
planned_end_timestamp | long | Geplanter Endzeitpunkt (Millisekunden) |
external_id | String | Arbeitsauftragsnummer des externen Systems (MES·ERP, bis 100 Zeichen). Wird als Paar mit external_system identifiziert — 11.6 |
external_system | String | Name des externen Systems, das den Arbeitsauftrag erstellt hat (bis 50 Zeichen) — zweite Hälfte des externen Identifikationspaares |
customer_po_id | String | Kundenbestellnummer (PO) für diesen Arbeitsauftrag (Optional) |
status | String | (Nur Antwort) Aktueller Status — Gespeicherte Werte WAIT·START·PAUSED·END·ABORTED |
isa95_state | String | (Nur Antwort) ISA-95 Status des Arbeitsauftrags — Ready·Running·Held·Completed·Aborted (11.1) |
title → order_name, fix_start_timestamp·fix_end_timestamp → planned_start_timestamp·planned_end_timestamp,
external_order_id → external_id, external_po_id → customer_po_id. Alte Namen werden weder in Anfragen gelesen noch in Antworten ausgegeben —
Upgrade-Notes.
11.4 Anwendungsbeispiele
Erstellung eines Arbeitsauftrags
import plantpulse.api.v5.dto.Quantity;
import plantpulse.api.v5.dto.request.OrderRequestV5;
import plantpulse.api.v5.dto.response.OrderResponseV5;
OrderRequestV5 req = new OrderRequestV5();
req.setOrder_id("ORDER_000001");
req.setOrder_name("5월 14일 1교대 생산");
req.setDescription("PROD_A001 500개 생산");
req.setSite_id("SITE_DJ");
req.setAsset_id("ASSET_DJ_M_0001");
req.setProduct_id("PROD_A001");
req.setCustomer_id("CUST_001");
req.setEmployee_id("EMP_E12345");
req.setPlanned_quantity(Quantity.of("500", "EA")); // 값은 10진 «문자열», 단위는 UN/ECE Rec 20 코드
req.setTime_per_unit_in_ms(5_000);
long now = System.currentTimeMillis();
req.setPlanned_start_timestamp(now);
req.setPlanned_end_timestamp(now + 4 * 3600_000L);
req.setExternal_id("MES-2026-0514-001");
req.setExternal_system("MES");
OrderResponseV5 created = client.order().create(req);
Standard-Lebenszyklus
String orderId = "ORDER_000001";
// WAIT → START
if (!client.order().start(orderId)) {
System.err.println("시작 실패 — planned_start_timestamp가 미래이거나 이미 진행중");
return;
}
// 잠시 후 — 일시중지
client.order().pause(orderId);
// 재개
client.order().resume(orderId);
// 정상 종료
client.order().end(orderId);
Abnormaler Abschluss
// abort 는 별도 인자 없이 호출. 상세 사유는 update() 로 description/notes 에 기록.
if (!client.order().abort("ORDER_000001")) {
System.err.println("중단 실패");
}
Einzelabfrage / Existenzprüfung
OrderResponseV5 o = client.order().get("ORDER_000001");
if (o != null) {
System.out.println("상태: " + o.getStatus());
Quantity planned = o.getPlanned_quantity(); // {quantity_string, data_type, unit_of_measure}
System.out.println("계획: " + planned.getQuantity_string() + " " + planned.getUnit_of_measure());
java.math.BigDecimal value = planned.toBigDecimal(); // 계산은 BigDecimal 로 — double 로 바꾸지 않는다
}
boolean exists = client.order().exists("ORDER_000001");
Gesamte Liste
import java.util.List;
List<OrderResponseV5> all = client.order().list();
for (OrderResponseV5 o : all) {
System.out.printf("[%s] %s — %s%n",
o.getStatus(), o.getOrder_id(), o.getOrder_name());
}
Nur laufende Arbeitsaufträge (Client-seitige Filterung)
import java.util.stream.Collectors;
List<OrderResponseV5> active = client.order().list().stream()
.filter(o -> "START".equals(o.getStatus())
|| "PAUSE".equals(o.getStatus()))
.collect(Collectors.toList());
Arbeitsaufträge nach Anlage
String assetId = "ASSET_DJ_M_0001";
List<OrderResponseV5> assetOrders = client.order().list().stream()
.filter(o -> assetId.equals(o.getAsset_id()))
.collect(Collectors.toList());
Statistiken nach Status
import java.util.Map;
Map<String, Long> byStatus = client.order().list().stream()
.collect(Collectors.groupingBy(
OrderResponseV5::getStatus,
Collectors.counting()));
byStatus.forEach((status, count) ->
System.out.printf("%s: %d건%n", status, count));
Bearbeiten / Löschen
// 수정 (계획 시간 연장)
OrderRequestV5 update = new OrderRequestV5();
update.setOrder_id("ORDER_000001");
update.setOrder_name("5월 14일 1교대 생산 (연장)");
// ... 모든 필드 다시 세팅 ...
update.setPlanned_end_timestamp(System.currentTimeMillis() + 8 * 3600_000L);
client.order().update("ORDER_000001", update);
// 삭제 (취소 처리)
client.order().delete("ORDER_000001");
11.5 Menge — ISA-95 Quantity
Die Menge eines Arbeitsauftrags (geplant, produziert, Gutteile, Ausschuss, Nacharbeit ...) ist kein einzelner Zahlenwert, sondern ein Objekt, das Wert und Einheit enthält.
Die Struktur entspricht 1:1 den QuantityValueType von ISA-95(IEC 62264) / B2MML V0700.
Basis sind V5 API (OpenAPI info.version 5.0), Mengenvereinbarung 2026-10-30, Namenswave 2026-10-31 und Platform-Version November 2026 (server-web 974891b4).
Events folgen dem Schema plantpulse.order.*·plantpulse.calendar.* Major 2, plantpulse.kpi.oee.finalized Major 1; DB nutzt Flyway V99·V100·V103 und Core-Migration V12V16·V21V23 —
Upgrade-Notes.
[
{ "quantity_string": "1250.5", "data_type": "decimal", "unit_of_measure": "KGM" },
{ "quantity_string": "1200", "data_type": "integer", "unit_of_measure": "EA" }
]
| Feld | B2MML | Typ | Regel |
|---|---|---|---|
quantity_string | QuantityString | string | Exakte Dezimaldarstellung — Exponentialdarstellung verboten, Dezimaltrennzeichen ist ., bis zu vier Dezimalstellen. Zähleinheiten müssen Ganzzahlen sein |
data_type | DataType | string | integer (Zähleinheit) oder decimal (Sonstige). Wird vom Server basierend auf der Einheit festgelegt — kann in der Anfrage weggelassen werden; wenn angegeben, muss es zur Einheit passen |
unit_of_measure | UnitOfMeasure | string | UN/ECE Recommendation 20 Common Code — siehe folgende Liste |
B2MML definiert dies als QuantityString. Zudem lesen die meisten JSON-Parser Zahlen als Double, was zu Präzisionsverlusten bei Dezimalzahlen führt. Verwenden Sie im SDK Quantity.toBigDecimal() zum Lesen und Berechnen. Bei der Erstellung einer Anfrage nutzen Sie
Quantity.of("1250.5", "KGM") — wenn data_type leer bleibt, füllt der Server dies automatisch aus.
Einheiten — Zulassungsliste (UN/ECE Rec 20)
| Code | Bedeutung | data_type | Bildschirmsymbol |
|---|---|---|---|
EA | each — Stückzählung | integer | EA |
H87 | piece | integer | pc |
C62 | one (unit) | integer | unit |
BX | box — Anzahl Boxen | integer | box |
SET | set — Anzahl Sätze/Kits | integer | set |
KGM | kilogram | decimal | kg |
GRM | gram | decimal | g |
TNE | tonne | decimal | t |
LTR | litre | decimal | L |
MLT | millilitre | decimal | mL |
MTQ | cubic metre | decimal | m³ |
MTR | metre | decimal | m |
MTK | square metre | decimal | m² |
- Es sind insgesamt 13 Einheiten zulässig; die Zähleinheiten sind
EA·H87·C62·BX·SET. Codes außerhalb dieser Liste werden abgelehnt (quantity.unit_invalid). Die Codes werden exakt (inklusive Groß-/Kleinschreibung) verglichen —ea,KG,PCSsind keine zulässigen Codes. - Wenn ein Code empfangen wird, der kein Bildschirmsymbol hat (z. B. Altdaten), wird der Code selbst angezeigt.
- Einheitenumrechnungen werden nicht durchgeführt (dies ist Aufgabe des MES). Mengen mit unterschiedlichen Einheiten werden nicht addiert.
- Bildschirmsymbole sind sprachunabhängig — auch in koreanischen Oberflächen wird «개» nicht verwendet, sondern
EA. Symbole werden immer angehängt (auch bei Stückzahlen).
Feldbezeichnungen — ISO 22400
Die Feldbezeichnungen folgen der Terminologie von ISA-95 und ISO 22000-2 (KPI-Gegenstück zu IEC 62264). Alte Namen erscheinen nicht mehr in Antworten (keine Kompatibilitätsfelder).
| Bedeutung | Feld (Quantity) | Altes Feld | Grundlage |
|---|---|---|---|
| Geplante Menge | planned_quantity | target_units + unit | ISA-95 MaterialRequirement.Quantity · ISO 22400 POQ |
| Produktionsmenge | produced_quantity | total_production_count | ISO 22400 PQ |
| Gutteilmenge | good_quantity | total_good_count · good_count | ISO 22400 GQ |
| Ausschussmenge | scrap_quantity | total_bad_count · bad_count — Bedeutung wurde eingegrenzt: Altes Feld war Gesamtausschuss, neues Feld nur physischer Ausschuss | ISO 22400 SQ |
| Nacharbeitsmenge | rework_quantity | (Keines — neues Feld) | ISO 22400 RQ |
| Geplant außerhalb Gutteil / Ausschuss | good_quantity_out_of_plan / scrap_quantity_out_of_plan | out_of_plan_good_count / out_of_plan_bad_count | |
| Gemessene Gutteile / Ausschuss (PLC) | measured_good_quantity / measured_scrap_quantity | measured_good_count / measured_bad_count | |
| Korrektur +/- | good_quantity_delta / scrap_quantity_delta | good_delta / bad_delta | |
| Korrektureingabewert | entered_good_quantity / entered_scrap_quantity | entered_good / entered_bad | |
| Prüfmenge | inspected_quantity | inspected_count | |
| Summe Prüfausschuss | inspected_scrap_quantity | inspected_bad_count | |
| Ausschussaufzeichnung nach Verwertung | scrap_quantity / rework_quantity | scrap_count / rework_count | ISO 22400 SQ / RQ |
Geänderte Antworten: /order, /order/query(include=oee), /order/{id}/oee, /order/{id}/quantity (inkl. Revisionshistorie),
/defects, /order/performance, /kpi/oee/history, /asset/{id}/status, MCP-Arbeitsauftragswerkzeug, Produktionsereignis OEE_CALCULATED.
- Die Felder
planned_quantity·good_quantity·scrap_quantityvon/asset/{id}/statuswerden in der Einheit des laufenden Arbeitsauftrags ausgegeben. Wenn kein Arbeitsauftrag läuft, ist der Wert null. - Verhältnisfelder (
total_good_rate,production_rate, Verfügbarkeit·Leistung·Qualität·OEE) sind dimensionslos und daher einfache Zahlen. - In
/asset/{id}/statusgibt es ebenfallsrework_quantity(Nacharbeit des laufenden Arbeitsauftrags). - PLC-Zähleraufzeichnungen (
good_quantity·scrap_quantityvonGET /api/v5/kpi/oee/count) und Ursachenausschuss in MCPget_asset_kpi(scrap_quantity) sind Quantity-Werte in der Einheit des Arbeitsauftrags zu diesem Zeitpunkt. Da Zähler Ganzzahlen verwenden, gilt Count 1 = 1 Einheit des Arbeitsauftrags — ein Ganzzahlzähler an einem kg-Arbeitsauftrag zählt nur in 1-kg-Schritten. Dezimalwerte werden nicht über Zähler, sondern über Mengenkorrekturen oder Leistungseingaben erfasst.
Ausschuss und Nacharbeit — «Ausschuss» als Summe
Gemäß ISO 22400 wird Ausschuss in physischen Ausschuss (SQ) und Nacharbeit (RQ) unterteilt.
- Ausschuss = physischer Ausschuss + Nacharbeit, Produktion = Gutteile + physischer Ausschuss + Nacharbeit (
produced_quantity=good_quantity+scrap_quantity+rework_quantity). scrap_quantitybezieht sich nur auf physischen Ausschuss. Vom PLC gezählte Fehler werden, da die Verwertung unbekannt ist, als physischer Ausschuss gezählt. Nacharbeit entsteht nur aus Fehleraufzeichnungen mit der VerwertungREWORK.- Die Qualitätsrate (Q) ist Gutteile ÷ Produktion, daher mindert auch Nacharbeit die Qualität — sie wird lediglich getrennt aufgeführt, der OEE-Wert bleibt unverändert.
- In der Benutzeroberfläche wird diese Unterscheidung textlich eingehalten: Stellen, die nur physischen Ausschuss angeben (Spalte Produktionshistorie, Feld Mengenkorrektur), werden als «Ausschuss» bezeichnet. Stellen, die die Summe anzeigen, heißen «Ausschuss», wobei bei vorhandener Nacharbeit Details wie «14 kg (Ausschuss 12,75 · Nacharbeit 1,25)» angehängt werden — Produktionsmanagement — Menge und Einheit.
- Wenn eine Integration eine «Ausschusssumme» benötigt, addieren Sie
scrap_quantity+rework_quantityals Dezimalzahlen innerhalb derselben Einheit. Lesen Siescrap_quantitynicht allein als Ausschusssumme.
Zuweisung der Mengen zu den Feldern — Zählertabelle
| Quelle (Speicherung) | V5-Feld / Event-Feld | Erfasste Menge |
|---|---|---|
PLC-Zählerhauptbuch tm_kpi_oee_count | good_quantity · scrap_quantity von /kpi/oee/count | PLC-gemessene Inkremente für Gutteile/Ausschuss. Da Verwertung unbekannt: Ausschuss = physischer Ausschuss (SQ) |
Arbeitsauftrags-OEE-Zeile mm_order_oee.total_production_count | produced_quantity · Event pq/pq_quantity | Produktion (PQ) = Gutteile + physischer Ausschuss + Nacharbeit |
mm_order_oee.total_good_count | good_quantity · gq/gq_quantity | Gutteile (GQ) |
mm_order_oee.total_bad_count − total_rework_count | scrap_quantity · sq/sq_quantity | physischer Ausschuss (SQ). total_bad_count selbst (Ausschusssumme) wird nicht über die Leitung übertragen |
mm_order_oee.total_rework_count | rework_quantity · rq/rq_quantity | Nacharbeit (RQ) |
mm_order_oee.out_of_plan_good_count / out_of_plan_bad_count | good_quantity_out_of_plan / scrap_quantity_out_of_plan · gq_out_of_plan/sq_out_of_plan(+_quantity) | Während geplanter Stillstände produzierte Menge — enthalten in obigen Gutteilen/Ausschuss, wird bei Effizienzberechnung abgezogen |
Mengenkorrektur mm_order_quantity_correction | measured_*_quantity · good_quantity_delta/scrap_quantity_delta · (Historie) entered_*_quantity von /order/{id}/quantity | PLC-Messwert, Korrektur +/- , REPLACE-Eingabewert. Das Ausschussfeld enthält nur physischen Ausschuss |
Fehleraufzeichnung mm_defect_record (Verwertung SCRAP/REWORK) | quantity·inspected_quantity von /defects, Leistungsdokument defects.scrap_quantity / rework_quantity / inspected_scrap_quantity | physischer Ausschuss/Nacharbeit nach Verwertung, Summe Prüfausschuss (SCRAP + REWORK) |
mm_order.planned_quantity | planned_quantity · Event planned_quantity | Geplant (POQ) |
Anfrageregeln und Ablehnung
Mengen, die in Leistungs-, Korrektur- oder Fehleraufzeichnungen eingetragen werden, müssen die gleiche Einheit wie der Arbeitsauftrag planned_quantity haben. Der Server führt keine Umrechnung durch und lehnt die Anfrage ab.
Die Ablehnung von Wert/Einheit erfolgt über 422 E1002 (nicht 400). In der Antwort (application/problem+json) gibt code den Wert E1002 an, und das Feld reason enthält den folgenden Fehlercode. Da detail ein in der Sprache des Aufrufers verfasster Satz ist, führen Sie Verzweigungen über reason durch.
| Fehlercode | Zeitpunkt |
|---|---|
quantity.unit_mismatch | Eine andere Einheit als die des Arbeitsauftrags wurde gesendet |
quantity.not_integer | Ein Dezimalwert für eine Zähleinheit (EA·H87·C62·BX·SET) wurde gesendet |
quantity.unit_invalid | Einheit fehlt oder liegt außerhalb der 13 zulässigen Einheiten |
quantity.format | quantity_string ist kein Dezimal-String (Exponentialdarstellung·führende Null·Zeichen +·Zahlentyp) oder data_type passt nicht zur Einheit |
quantity.scale | Mehr als vier Dezimalstellen |
quantity.negative | Negativer Wert (nur Korrektur +/- Felder akzeptieren negative Werte) |
quantity.range | Absolutwert ≥ 10¹⁴ — außerhalb des Speicherbereichs von numeric(18,4) |
- Wenn statt eines Objekts ein einfacher Wert (z. B. Zahl
500) in einem Mengenfeld angegeben wird oder Schlüssel außerhalb vonquantity_string·data_type·unit_of_measureverwendet werden, erfolgt eine Antwort 400E1000(Formatfehler). - Die geplante Menge eines Arbeitsauftrags muss größer als 0 sein.
Perioden-KPI — Keine Aggregation bei gemischten Einheiten
Antworten, die mehrere Arbeitsaufträge zusammenfassen (wie /kpi/period·/kpi/daily), bilden Summen nur dann, wenn alle eine einzige Einheit haben.
Die Summenfelder für Mengen befinden sich in good_count·total_count·in_plan_count innerhalb des Objekts oee von /kpi/period sowie in good_count·bad_count·planned_count von /kpi/daily.
Die Gesamtausschusssumme in bad_count von /kpi/daily entspricht Produktion − Gutteile, also Ausschuss (physischer Ausschuss + Nacharbeit).
- Eine einzige Einheit: Die Summenfelder für Mengen sind wie bisher Zahlen, ergänzt durch die Einheit
unit_of_measure. - Gemischte Einheiten: Die Summenfelder für Mengen sowie
unit_of_measuresind null; stattdessen enthältquantities_by_unitdie Gutteil- und Produktionsmengen pro Einheit als Quantity-Objekte.
{
"good_count": null,
"total_count": null,
"in_plan_count": null,
"unit_of_measure": null,
"quantities_by_unit": [
{ "unit_of_measure": "EA",
"good_quantity": { "quantity_string": "2671", "data_type": "integer", "unit_of_measure": "EA" },
"produced_quantity": { "quantity_string": "2700", "data_type": "integer", "unit_of_measure": "EA" } },
{ "unit_of_measure": "KGM",
"good_quantity": { "quantity_string": "1250.5", "data_type": "decimal", "unit_of_measure": "KGM" },
"produced_quantity": { "quantity_string": "1302", "data_type": "decimal", "unit_of_measure": "KGM" } }
]
}
Verhältnisse (Verfügbarkeit·Leistung·Qualität·OEE) sind dimensionslos und werden auch bei gemischten Einheiten normal ausgegeben.
EMS-Wert pro Einheit — Einheit des Nenners
Der Nenner in energy_per_unit_kwh·co2_per_unit_kg ist die Gutteilmenge des Arbeitsauftrags, daher wird in der Antwort die entsprechende Einheit unit_of_measure mitgegeben
(/order/{id}/ems, /order/ems/*, /order/query?include=ems). Die Anzeige erfolgt in Formaten wie «kWh/EA», «kWh/kg».
Bei Aggregationen mehrerer Arbeitsaufträge mit gemischten Einheiten sind der Wert pro Einheit und die Einheit null.
Events
Da das Event-Schema nur «Anhängen am Ende» zulässt, wurden Felder hinzugefügt, ohne die Typen zu ändern.
| Event | Mengenfeld |
|---|---|
plantpulse.order.* | planned_quantity(number) + planned_quantity_unit_of_measure(Rec 20 Code) |
plantpulse.kpi.oee.finalized | Referenzwerte gq_quantity·sq_quantity·rq_quantity·pq_quantity·gq_out_of_plan_quantity·sq_out_of_plan_quantity(number) + unit_of_measure. sq bezieht sich nur auf physischen Ausschuss, Nacharbeit erfolgt über rq(pq = gq + sq + rq). Ganzzahlfelder gq·sq·rq·pq·... werden nur bei Zähleinheiten befüllt und fehlen bei Dezimaleinheiten — sie werden im nächsten Major-Release entfernt |
Produktionsereignis OEE_CALCULATED | good_quantity·scrap_quantity(nur physischer Ausschuss)·rework_quantity = Quantity-Objekt |
11.6 MES-Integration — Leistungsfeed und B2MML-Zuordnung
Identifikation externer Arbeitsaufträge — (external_system, external_id)-Paar
Arbeitsaufträge von Kundensystemen (MES·ERP) werden über ein Paar aus dem Namen des ausstellenden Systems und der Nummer innerhalb dieses Systems identifiziert — analog zur externen Identifikation von Mitarbeiter- oder Instandhaltungsaufträgen.
- Das Paar ist sowohl beim Empfang als auch beim Versand präsent. V5
POST·PUT·PATCH /api/v5/orderempfangenexternal_system(50 Zeichen) undexternal_id(100 Zeichen);GET /order/{id}·Listen·/order/queryund Leistungsdokumente übertragen beide Werte stets (wenn nicht vorhanden, null). Da im Konsolenformular kein Feldexternal_systemexistiert, erfolgt die Eingabe über V5. - Leere Werte oder Werte, die nur aus Leerzeichen bestehen, werden als null gespeichert. Überschreitungen der Länge oder Steuerzeichen führen zu 422
order.external_ref.invalid. - Das Paar ist eindeutig, sofern nicht beide Felder leer sind. Die Zuweisung desselben Paares zu einem zweiten Arbeitsauftrag führt zu 409
order.external.duplicate. PUTersetzt die gesamte Anfrage — fehlendeexternal_system·external_idwerden gelöscht. Für Teiländerungen verwenden SiePATCH.- Arbeitsaufträge, die nur
external_id, aber keinexternal_systembesitzen, werden weiterhin akzeptiert, können jedoch nicht über die untenstehende «Suche nach Paar» gefunden werden. - Events übertragen ebenfalls das Paar: In
plantpulse.order.*(Schema Major 2) übertragencreated·updated·startedaborteddie Werteexternal_id·external_system; Transitions-Events (startedaborted) übertragen zusätzlichcustomer_po_id. - Um einen Arbeitsauftrag über das Paar zu lesen, nutzen Sie
GET /api/v5/order/by-external/{system}/{external_id}— bei Nichtexistenz 404, bei einer leeren Seite des Paares 422order.external_ref.invalid. Der Filter in/order/querybesteht ebenfalls ausexternal_id+external_system. Das Senden des alten Parametersexternal_order_idführt nicht zum Ignorieren, sondern zu einer Ablehnung mit 422.
Pfade des Leistungsfeeds
| HTTP | Pfad | Funktion |
|---|---|---|
| GET | /api/v5/order/performance | Leistungsfeed — cursor·site_id·limit. Arbeitsaufträge mit geänderter Leistung erhalten einen höheren Wert in performance_revision und erscheinen erneut am Ende des Feeds |
| GET | /api/v5/order/{order_id}/performance | Leistungsdokument eines einzelnen Arbeitsauftrags |
| GET | /api/v5/order/performance/by-external/{external_system}/{external_id} | Suche nach Paar — Array (da Paare eindeutig, maximal ein Element), sonst leeres Array |
/api/v5/order/performance/by-external/{external_order_id} (Nummer ohne System) wurde entfernt. Es gibt keine Kompatibilitätspfade.
Mengenschlüssel im Leistungsdokument
| Position | Schlüssel (alles Quantity) | Alter Schlüssel |
|---|---|---|
plan | planned_quantity | target_units |
quantity | measured_good_quantity / measured_scrap_quantity | measured_good / measured_bad |
quantity | good_quantity / scrap_quantity | good / bad |
quantity.correction | good_quantity_delta / scrap_quantity_delta | good_delta / bad_delta |
oee | good_quantity / scrap_quantity | total_good_count / total_bad_count |
defects | inspected_scrap_quantity / scrap_quantity / rework_quantity | inspected_bad_count / scrap_count / rework_count |
quantity.correction_version, progress.expected_now_units·pace_units behalten ihre Namen (bei Dezimaleinheiten sind es Dezimalzahlen).
quantity.scrap_quantity bezieht sich nur auf physischen Ausschuss (PLC-Fehler + Aufzeichnung SCRAP) und ist gleichbedeutend mit defects.scrap_quantity. quantity.rework_quantity hat den gleichen Wert wie defects.rework_quantity. defects.inspected_scrap_quantity umfasst den gesamten Prüfausschuss (SCRAP + REWORK).
Status des Leistungsdokuments — Auswertung von Änderungen
Ein Leistungsdokument enthält den aktuellen Status eines Arbeitsauftrags; bei jeder Statusänderung erhöht sich die Revisionsnummer.
| Feld | Bedeutung |
|---|---|
actual.status | Gespeicherter Status WAIT·START·PAUSED·END·ABORTED — 11.1. Stornierung ist ABORTED + actual.abort_code=CANCELLED |
actual.isa95_state | ISA-95 Status des Arbeitsauftrags Ready·Running·Held·Completed·Aborted |
performance_revision | Anzahl der Leistungsänderungen. Erhöht sich bei jeder Änderung um 1; der Feed setzt den Arbeitsauftrag dann ans Ende. 0 markiert einen noch nicht beendeten Arbeitsauftrag — nicht im Feed vorhanden, nur über /order/{id}/performance lesbar |
quantity.correction_version | Revisionsnummer der Mengenkorrektur. Ohne Korrektur entspricht dies dem Messwert; erhöht sich bei jeder Korrektur — Historie siehe Revisionsverlauf in /order/{id}/quantity |
changed_at · change_cause | Zeitpunkt der letzten Änderung und deren Ursache — ENDED·QUANTITY(Mengenkorrektur)·STOP_REASON·OEE_FINAL·DEFECT(Fehleraufzeichnung)·PROGRESS·BASELINE |
Mengen werden ausschließlich als «Wert + Einheit» übertragen; nicht berechnete Felder werden als null statt 0 ausgegeben. Das MES ersetzt ein Dokument vollständig durch ein neues Dokument mit derselben order_id und einer höheren performance_revision.
B2MML-Zuordnungstabelle
Ein Leistungsdokument entspricht der Job Response (Segment Response) von ISA-95 Part 4; die darin enthaltenen Mengen entsprechen der Quantity von Material Actual (Produced).
| ISA-95 / B2MML | PlantPulse V5 | Bemerkung |
|---|---|---|
QuantityValueType — QuantityString · DataType · UnitOfMeasure | Quantity — quantity_string · data_type · unit_of_measure | 1:1. Die B2MML-Optionalfelder Key werden nicht verwendet |
UnitOfMeasure Wert | UN/ECE Rec 20 Code | Zulassungsliste siehe 11.5 |
| ID des Job Order | external_id | Name des ausstellenden Systems ist external_system — beide bilden ein Paar |
| Quantity von Job Order · MaterialRequirement | planned_quantity | ISO 22400 POQ |
| Name des Job Order | order_name | |
| StartTime · EndTime des Job Order | planned_start_timestamp · planned_end_timestamp | Geplante Zeit. Tatsächliche Zeit ist actual_start_timestamp · actual_end_timestamp |
| Job Response | Ein Leistungsdokument (/order/{id}/performance) | |
| Quantity von MaterialActual(Produced) | produced_quantity | ISO 22400 PQ |
| Davon Gutteile | good_quantity | ISO 22400 GQ |
| Davon Ausschuss | scrap_quantity | ISO 22400 SQ |
| Davon Nacharbeit | defects.rework_quantity | ISO 22400 RQ |
11.7 Nutzungsszenarien
Szenario — Automatische Erstellung von Arbeitsaufträgen via MES-Integration
import java.text.SimpleDateFormat;
import java.util.Date;
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
String today = df.format(new Date());
// 외부 MES 큐에서 받은 주문을 V5 Order로 변환
for (MesOrder mes : mesQueue) {
OrderRequestV5 req = new OrderRequestV5();
req.setOrder_id("ORDER_" + today + "_" + String.format("%03d", mes.seq));
req.setSite_id("SITE_DJ");
req.setAsset_id(mes.equipId);
req.setProduct_id(mes.productId);
// MES 수량을 그대로 — 단위 환산은 하지 않는다. 단위는 허용 목록(11.5) 안의 Rec 20 코드여야 한다
req.setPlanned_quantity(Quantity.of(mes.qty.toPlainString(), mes.unitCode));
req.setExternal_id(mes.mesOrderId);
req.setExternal_system("MES");
req.setPlanned_start_timestamp(mes.plannedStart);
req.setPlanned_end_timestamp(mes.plannedEnd);
client.order().create(req);
}
Szenario — Helper für sichere Zustandsübergänge
public static boolean safeStart(APIClient_V5 client, String orderId) {
OrderResponseV5 o = client.order().get(orderId);
if (o == null) {
log.warn("작업지시 없음: " + orderId);
return false;
}
if (!"WAIT".equals(o.getStatus())) {
log.warn("WAIT 상태가 아님: " + o.getStatus());
return false;
}
return client.order().start(orderId);
}
Nächste Schritte
- Customer-Service, Employee-Service, Product-Service — Stammdaten, die mit Orders verknüpft sind
- Calendar-Service — Konfliktprüfung zwischen Arbeitsaufträgen und Inspektionsplänen
- Upgrade-Notes — Erforderliche Anpassungen bei der Umstellung auf Quantity-Mengen