7. Asset-Service
Der Zugriff erfolgt über client.asset(). Kernstück des PlantPulse-Assetmodells — verwaltet den Hierarchiebaum Site > Area > Line > Equipment.
ID-Regel: Präfix
ASSET_ist zwingend erforderlich. Die TypcodesA/L/Mbestimmen die Baumhierarchie. Details siehe Domänen-ID-Regeln.
7.1 Methodenübersicht
| Methode | Rückgabetyp | HTTP | Endpunkt |
|---|---|---|---|
create(AssetRequestV5) | AssetResponseV5 oder null | POST | /api/v5/asset |
update(asset_id, AssetRequestV5) | AssetResponseV5 oder null | PUT | /api/v5/asset/{id} |
delete(asset_id) | boolean | DELETE | /api/v5/asset/{id} |
get(asset_id) | AssetResponseV5 oder null | GET | /api/v5/asset/{id} |
list() | List<AssetResponseV5> | GET | /api/v5/asset |
exists(asset_id) | boolean | GET | /api/v5/asset/{id}/exists |
Der Asset-Service konzentriert sich auf vereinfachtes CRUD. Für Abfragen der Baumhierarchie verwenden Sie den Path-Service oder eine clientseitige Filterung (
list()mit anschließendemasset_type-Filter).
7.2 Asset-Type-Werte
| asset_type | Bedeutung |
|---|---|
A | Area (Bereich) |
L | Line (Linie) |
M | Equipment (Anlage, Maschine) |
7.3 AssetRequestV5 / AssetResponseV5
| Feld | Typ | Beschreibung |
|---|---|---|
asset_id | String | Asset-ID (PK, ASSET_ erforderlich) |
asset_name | String | Anzeigename |
parent_asset_id | String | ID des übergeordneten Assets |
asset_order | String | Sortierreihenfolge unter Geschwisterelementen |
asset_type | String | A/L/M |
table_type | String | Anlagenklassifizierung (CNC, INJECTION usw.) |
site_id | String | Zugehörige Site |
description | String | Beschreibung |
insert_date / update_date | String | (nur Antwort) Zeitstempel |
7.4 Anwendungsbeispiele
Baum Area → Line → Equipment anlegen
import plantpulse.api.v5.dto.request.AssetRequestV5;
// 1) Area
AssetRequestV5 area = new AssetRequestV5();
area.setSite_id("SITE_DJ");
area.setParent_asset_id("SITE_DJ");
area.setAsset_id("ASSET_DJ_A_0001");
area.setAsset_name("조립구역");
area.setAsset_type("A");
client.asset().create(area);
// 2) Line
AssetRequestV5 line = new AssetRequestV5();
line.setSite_id("SITE_DJ");
line.setParent_asset_id("ASSET_DJ_A_0001");
line.setAsset_id("ASSET_DJ_L_0001");
line.setAsset_name("1번 조립 라인");
line.setAsset_type("L");
client.asset().create(line);
// 3) Equipment (CNC 머신)
AssetRequestV5 cnc = new AssetRequestV5();
cnc.setSite_id("SITE_DJ");
cnc.setParent_asset_id("ASSET_DJ_L_0001");
cnc.setAsset_id("ASSET_DJ_M_0001");
cnc.setAsset_name("CNC #1");
cnc.setAsset_type("M");
cnc.setTable_type("CNC");
cnc.setDescription("DMG MORI NLX-2500");
client.asset().create(cnc);
Einzelabfrage
import plantpulse.api.v5.dto.response.AssetResponseV5;
AssetResponseV5 cnc = client.asset().get("ASSET_DJ_M_0001");
if (cnc != null) {
System.out.println(cnc.getAsset_name() + " (" + cnc.getAsset_type() + ")");
System.out.println("부모: " + cnc.getParent_asset_id());
}
Gesamtliste + Filterung nach Typ
V5 besitzt keine listByType-Methode, daher erfolgt die Filterung clientseitig.
import java.util.List;
import java.util.stream.Collectors;
List<AssetResponseV5> all = client.asset().list();
// Equipment만
List<AssetResponseV5> equipments = all.stream()
.filter(a -> "M".equals(a.getAsset_type()))
.collect(Collectors.toList());
// 대전공장의 Line만
List<AssetResponseV5> djLines = all.stream()
.filter(a -> "SITE_DJ".equals(a.getSite_id()))
.filter(a -> "L".equals(a.getAsset_type()))
.collect(Collectors.toList());
Baum rekonstruieren (clientseitig)
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
// asset_id 인덱스
Map<String, AssetResponseV5> byId = new HashMap<>();
for (AssetResponseV5 a : client.asset().list()) {
byId.put(a.getAsset_id(), a);
}
// 부모-자식 매핑
Map<String, List<AssetResponseV5>> children = new HashMap<>();
for (AssetResponseV5 a : byId.values()) {
children
.computeIfAbsent(a.getParent_asset_id(), k -> new ArrayList<>())
.add(a);
}
// 사이트(SITE_DJ) 산하 트리 출력
printTree(children, "SITE_DJ", 0);
static void printTree(Map<String, List<AssetResponseV5>> children, String id, int depth) {
List<AssetResponseV5> kids = children.getOrDefault(id, List.of());
for (AssetResponseV5 c : kids) {
System.out.println(" ".repeat(depth) + c.getAsset_id() + " — " + c.getAsset_name());
printTree(children, c.getAsset_id(), depth + 1);
}
}
Asset ändern
AssetRequestV5 update = new AssetRequestV5();
update.setSite_id("SITE_DJ");
update.setParent_asset_id("ASSET_DJ_L_0001");
update.setAsset_id("ASSET_DJ_M_0001");
update.setAsset_name("CNC #1 (보수 후)");
update.setAsset_type("M");
update.setTable_type("CNC");
update.setDescription("2026-05-10 베어링 교체 완료");
client.asset().update("ASSET_DJ_M_0001", update);
Asset löschen
⚠️ Vor dem Löschen eines Assets müssen zuerst alle damit verknüpften Tags und untergeordneten Assets gelöscht werden.
boolean ok = client.asset().delete("ASSET_DJ_M_OLD");
7.5 Anwendungsszenarien
Szenario — Equipment-Liste einer Site mit jeweiliger Tag-Anzahl
String siteId = "SITE_DJ";
List<AssetResponseV5> equipments = client.asset().list().stream()
.filter(a -> siteId.equals(a.getSite_id()))
.filter(a -> "M".equals(a.getAsset_type()))
.collect(Collectors.toList());
for (AssetResponseV5 eq : equipments) {
long tagCount = client.tag().countByAsset(eq.getAsset_id());
System.out.printf("%s — Tag %d개%n", eq.getAsset_name(), tagCount);
}
Szenario — Erfassung von OEE-Dashboard-Daten auf Line-Ebene
// 1) Line 목록
List<AssetResponseV5> lines = client.asset().list().stream()
.filter(a -> "L".equals(a.getAsset_type()))
.filter(a -> "SITE_DJ".equals(a.getSite_id()))
.collect(Collectors.toList());
// 2) 각 Line 산하 Equipment 조회 → 자산 경로 → 작업지시 → KPI 집계
for (AssetResponseV5 line : lines) {
List<AssetResponseV5> machines = client.asset().list().stream()
.filter(a -> line.getAsset_id().equals(a.getParent_asset_id()))
.collect(Collectors.toList());
for (AssetResponseV5 m : machines) {
long now = System.currentTimeMillis();
// 현재 작업지시는 Order 서비스로 조회
// ...
}
}
Nächste Schritte
- Tag-Service — Tags mit Assets verknüpfen
- Path-Service — Baumpfade in einem Zug abfragen