7. Assetサービス
client.asset() でアクセスします。PlantPulse資産モデルの核心である 企業 > サイト > 区域 > ライン > 設備 の5層ツリーを管理します。
ID規則: 区域
AREA_· ラインLINE_· 設備EQUIPMENT_(既存のASSET_も有効)。asset_idを空にした場合、Platformが発行します。ツリーの層を決定するのはIDではなくasset_typeです。詳細は ドメインID規則 を参照してください。
7.1 メソッド一覧
| メソッド | 戻り値の型 | HTTP | エンドポイント |
|---|---|---|---|
create(AssetRequestV5) | AssetResponseV5 または null | POST | /api/v5/asset |
update(asset_id, AssetRequestV5) | AssetResponseV5 または null | PUT | /api/v5/asset/{id} |
delete(asset_id) | boolean | DELETE | /api/v5/asset/{id} |
get(asset_id) | AssetResponseV5 または null | GET | /api/v5/asset/{id} |
list() | List<AssetResponseV5> | GET | /api/v5/asset |
exists(asset_id) | boolean | GET | /api/v5/asset/{id}/exists |
getByExternal(system, external_id) | AssetResponseV5 또는 null | GET | /api/v5/asset/by-external/{system}/{external_id} |
patchProperties(asset_id, 요청) | AssetResponseV5 또는 null | PATCH | /api/v5/asset/{id}/properties |
Assetサービスは簡素化されたCRUDに特化しています。ツリー階層の照会は Pathサービス またはクライアント側でのフィルタリング (
list()後にasset_typeフィルタ) を使用してください。
7.2 Asset Type 値
| asset_type | 意味 |
|---|---|
E | 企業 (Enterprise) — インストールにつき1つ、ツリーのルート |
S | サイト (Site) |
A | 区域 (Area) |
L | ライン (Line) |
M | 設備 (Equipment, Machine) |
POST /api/v5/asset で作成できるのは A · L · M です。サイトは Siteサービス で作成します。
GET /api/v5/asset は asset_type を指定しない場合は区域・ライン・設備を返し、asset_type=E や S を指定した場合はその層を返します。
E · S を設備としてカウントしないでください。 層はID接頭辞ではなく、この値で判断します。
7.3 AssetRequestV5 / AssetResponseV5
| フィールド | 型 | 説明 |
|---|---|---|
asset_id | String | 資産ID (PK)。空にした場合は発行 |
asset_name | String | 表示名 |
parent_asset_id | String | 親資産ID — 直上の層 |
asset_order | String | 兄弟間のソート順 |
asset_type | String | A/L/M (応答には E·S も)。作成後は変更不可 |
asset_class_code | String | 設備分類コード (CNC, INJECTIONなど)。その層の分類である必要があり、そうでない場合は 422 |
site_id | String | 所属サイト |
description | String | 説明 (必須) |
operational_status_code | String | (応答) 運転状態 |
external_system / external_id | String | (応答) 他のシステムがこのノードを呼ぶ番号 |
insert_date / update_date | String | (応答専用) 時刻 |
単件照会はその層の固有属性まで含み、一覧は共通項目 (operational_status_code · external_system · external_id) のみを返します。
固有属性 — /api/v5/asset/{id}/properties
層ごとに固有の属性があります。GET で読み取り、PATCH (または PUT) で修正します。送信したキーのみが適用され、null は削除となり、送信しなかったキーは維持されます。
| 層 | キー |
|---|---|
| 企業を除く共通 | operational_status_code, external_system + external_id (両方あるか、両方ないか) |
サイト S | timezone, country, site_code, address, lat, lng |
区域 A | area_function_code(PRODUCTION · STORAGE · UTILITY), responsible_employee_id |
ライン L | line_kind_code(PRODUCTION_LINE · PROCESS_CELL · PRODUCTION_UNIT), design_rate(時間あたり, 0超) + design_rate_unit_of_measure(UN/ECE Rec 20, 両方あるか、両方ないか), responsible_employee_id |
設備 M | manufacturer, model, serial_number, installed_date, commissioned_date(設置日以降), warranty_end_date(yyyy-MM-dd), criticality_code(A · B · C), functional_location(サイト内で一意) |
| 応答 | 意味 |
|---|---|
422 asset.invalid.<key> | その層にないキー、未知のコード、ペアの不足、日付順序違反 |
422 asset.invalid.asset_type | 層を変更しようとした — 層は変更されません |
409 asset.duplicate.external_id | 他のノードが同じ外部番号を使用している |
409 asset.duplicate.functional_location | 同じサイトの別の設備が同じ機能位置を使用している |
応答の effective_responsible_employee_id は実際の担当者です。自身の項目が空の場合は、最も近い上位 (ライン → 区域) の担当を継承し、effective_responsible_from_asset_id でどこから継承したかを示します。
GET /api/v5/asset/{id} 応答の qr_payload は QRラベル に印刷するアドレスです。この呼び出しは トークンを生成しません。コンソールでラベルを一度開き、トークンが生成された設備のみが埋められ、まだ存在しないかコンソールアドレスが空の場合は "" となります。
外部番号で検索
GET /api/v5/asset/by-external/MAXIMO/BEDFORD%2F11430
GET /api/v5/asset/by-external?system=MAXIMO&external_id=BEDFORD/11430
すべての層から検索します。存在しない場合は 404 asset.not_found 、システムと番号のいずれか一方のみが指定された場合は 422 となります。
7.4 使用例
区域 → ライン → 設備 ツリーの作成
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_name("조립구역");
area.setAsset_type("A");
client.asset().create(area);
// asset_id 를 비워 두면 플랫폼이 발급합니다 — 응답에서 AREA_000001 을 받습니다
// 2) Line
AssetRequestV5 line = new AssetRequestV5();
line.setSite_id("SITE_DJ");
line.setParent_asset_id("AREA_000001");
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("LINE_000001");
cnc.setAsset_name("CNC #1");
cnc.setAsset_type("M");
cnc.setAsset_class_code("CNC");
cnc.setDescription("DMG MORI NLX-2500");
client.asset().create(cnc);
単件照会
import plantpulse.api.v5.dto.response.AssetResponseV5;
AssetResponseV5 cnc = client.asset().get("EQUIPMENT_000001");
if (cnc != null) {
System.out.println(cnc.getAsset_name() + " (" + cnc.getAsset_type() + ")");
System.out.println("부모: " + cnc.getParent_asset_id());
}
全件一覧 + タイプ別フィルタリング
サーバー側フィルタは GET /api/v5/asset?asset_type=M · operational_status_code= · external_system= です。Javaクライアントの list() はフィルタを受け取らないため、受信後にフィルタリングを行います。
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());
ツリー再構成 (クライアント側)
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);
}
}
資産修正
AssetRequestV5 update = new AssetRequestV5();
update.setSite_id("SITE_DJ");
update.setParent_asset_id("LINE_000001");
update.setAsset_id("EQUIPMENT_000001");
update.setAsset_name("CNC #1 (보수 후)");
update.setAsset_type("M");
update.setAsset_class_code("CNC");
update.setDescription("2026-05-10 베어링 교체 완료");
client.asset().update("EQUIPMENT_000001", update);
資産削除
⚠️ 資産を削除する前に、その資産に接続されているすべてのタグ・下位資産を先に削除する必要があります。
boolean ok = client.asset().delete("EQUIPMENT_OLD");
7.5 活用シナリオ
シナリオ — サイトの設備一覧と各タグ数
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);
}
シナリオ — ライン単位のOEEダッシュボードデータ収集
// 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 서비스로 조회
// ...
}
}