2. ドメインID規則
PlantPulseのすべてのマスタデータはサーバ側の正規表現検証に従います。ドメインValidator(SiteValidator、OPCValidator、AssetValidator、TagValidator、…)が正規表現マッチングを強制し、違反するとcreate() / update()呼び出しがnullを返し、レスポンスenvelopeに_code=E1002 (VALIDATION_FAILED)が含まれます。正確なID設計は拡張可能なIoTシステム構築の出発点です。
📖 プラットフォーム全体の規約の要約はドメインIDネーミング規約ページを参照してください。
2.1 一目でわかるID規則(サーバ正規表現基準)
| ドメイン | Regex | 推奨パターン | 例 |
|---|---|---|---|
| Site | ^V?SITE_[A-Z0-9_]+$ | SITE_<token> (またはVSITE_… Virtual) | SITE_DJ, VSITE_AGG_01 |
| OPC | ^(OPC|EDGE|TEST)_[A-Z0-9_]+$ | OPC_<type>_<number> / EDGE_<location>_<number> | OPC_00303, EDGE_GW01, TEST_VIRTUAL |
| Edge | ^(EDGE|OPC)_[A-Z0-9_]+$ | EDGE_<location>_<number> | EDGE_LINE1_01 |
| Asset (Area/Line/Equipment) | ^ASSET_[A-Z0-9_]+$ | ASSET_<site>_<type>_<number> | ASSET_DJ_L_0001 |
| Tag | ^V*TAG_[A-Z0-9_]+$ | TAG_<OPC>_<number> (またはVTAG_ 仮想タグ) | TAG_EDGE_00303_90007, VTAG_OEE_LINE1 |
| AlarmConfig | ^ALARM_CONFIG_[A-Z0-9_]+$ | ALARM_CONFIG_<metric>_<number> | ALARM_CONFIG_TEMP_HIGH_01 |
| Employee | ^EMP_[A-Z0-9_]+$ | EMP_<employee-no> | EMP_E12345 |
| Customer | ^CUSTOMER_[A-Z0-9_]+$ | CUSTOMER_<number> | CUSTOMER_001 |
| Product | ^PRODUCT_[A-Z0-9_]+$ | PRODUCT_<SKU> | PRODUCT_A001 |
| Flow | ^FLOW_[A-Z0-9_]+$ | FLOW_<purpose>_<interval> | FLOW_OEE_DAILY |
| User (login) | ^[A-Z][A-Z0-9_]*$ | 大文字始まり、[A-Z0-9_] | ADMIN, OPERATOR_01 |
| Calendar | (自由) | CAL_<YYYYMMDD>_<seq> | CAL_20260514_0001 |
| Order | (自由) | ORD_<YYYYMMDD>_<seq> | ORD_20260514_001 |
⚠️ 検証の強制: 上表で正規表現が記載されているすべてのドメインはサーバ側で検査されます。違反時、V5は
nullを返し、_code=E1002、_message="site_id must match ^V?SITE_[A-Z0-9_]+$"などがレスポンスに含まれます。⚠️ Customer/Productは完全な単語:
CUSTOMER_、PRODUCT_が正しい接頭辞です。短いCUST_、PROD_は拒否されます。⚠️ API_接頭辞はOPCでは使用不可: 外部APIチャネルであっても
opc_idはOPC_/EDGE_/TEST_のいずれかで始まる必要があります。
2.2 Site ID
정규식: ^V?SITE_[A-Z0-9_]+$
허용: SITE_… 또는 VSITE_… (Virtual Site — 물리 사이트 없이 만드는 가상/집계용 사이트)
例
import plantpulse.api.v5.dto.request.SiteRequestV5;
import plantpulse.api.v5.dto.response.SiteResponseV5;
SiteRequestV5 req = new SiteRequestV5();
req.setSite_id("SITE_DJ"); // 대전공장
req.setSite_name("대전 1공장");
req.setLat("36.3504");
req.setLng("127.3845");
SiteResponseV5 created = client.site().create(req);
if (created == null) {
System.err.println("등록 실패 — site_id 정규식 확인 필요");
}
// Virtual Site (테스트·집계용)
SiteRequestV5 vsite = new SiteRequestV5();
vsite.setSite_id("VSITE_AGG_01");
vsite.setSite_name("집계 가상 사이트");
client.site().create(vsite);
❌ 誤った例(いずれもV5でnullを返す)
req.setSite_id("DJ_FACTORY"); // ❌ SITE_ 누락 → E1002
req.setSite_id("site_00001"); // ❌ 소문자 → E1002
req.setSite_id("00001"); // ❌ 접두사 없음 → E1002
req.setSite_id("VVSITE_01"); // ❌ V는 0 또는 1개만 (V?)
2.3 OPC ID
정규식: ^(OPC|EDGE|TEST)_[A-Z0-9_]+$
허용: OPC_… / EDGE_… / TEST_…
OPC IDはデータ収集の物理的・論理的な出所を表します。同じOPCタイプ内でも意味の分離が必要な場合は_で階層を表現します。
OPC Typeごとの推奨パターン
| OPC Type | 用途 | 推奨ID接頭辞 |
|---|---|---|
OPC | OPC UA / OPC DAサーバ | OPC_<ua-server-name>_<number> |
PLC | Siemens、Mitsubishi、Allen-Bradleyなど | OPC_PLC_<line>_<number> |
MODBUS | Modbus TCP/RTUデバイス | OPC_MB_<equipment>_<number> |
DATABASE | 外部RDBMSポーリング | OPC_DB_<system> |
FILE | REST API/ファイルインポート | OPC_FILE_<system>_<number> |
VIRTUAL | テスト・シミュレーション | TEST_VIRTUAL_<number> |
| Edge Gateway | エッジゲートウェイ(別途edge_idを使用) | EDGE_<location>_<number> |
⚠️ 過去の文書で
API_接頭辞に言及したことがありますが、現在のサーバ検証ではOPC_/EDGE_/TEST_のみ許可されます。外部API/ファイルチャネルであってもOPCドメインではOPC_FILE_…形式を使用してください。
例
import plantpulse.api.v5.dto.request.OPCRequestV5;
OPCRequestV5 req = new OPCRequestV5();
req.setOpc_id("OPC_EDGE_00303");
req.setOpc_name("Line1 Edge Gateway");
req.setOpc_type("PLC"); // OPC/PLC/MODBUS/DATABASE/FILE/VIRTUAL
req.setOpc_sub_type("SIEMENS_S7");
req.setSite_id("SITE_DJ");
req.setOpc_server_ip("192.168.10.50");
req.setOpc_agent_ip("192.168.10.5");
req.setOpc_agent_port(60000);
client.opc().create(req);
// ERP 연동 — OPC_FILE_ 접두사 (API_ 아님!)
OPCRequestV5 fileChannel = new OPCRequestV5();
fileChannel.setOpc_id("OPC_FILE_ERP_001");
fileChannel.setOpc_type("FILE");
fileChannel.setSite_id("SITE_DJ");
client.opc().create(fileChannel);
// 테스트·시뮬레이션
OPCRequestV5 testOpc = new OPCRequestV5();
testOpc.setOpc_id("TEST_VIRTUAL_001");
testOpc.setOpc_type("VIRTUAL");
testOpc.setSite_id("SITE_DJ");
client.opc().create(testOpc);
2.4 Edge ID
정규식: ^(EDGE|OPC)_[A-Z0-9_]+$
edge_idはエッジゲートウェイデバイスの識別子です。OPCと正規表現はほぼ同じですが、TEST_接頭辞は許可されません。
req.setEdge_id("EDGE_LINE1_01");
req.setEdge_id("OPC_EDGE_00303"); // OPC도 가능
// req.setEdge_id("TEST_EDGE_01"); // ❌ edge_id는 TEST_ 불가
2.5 Asset ID — 階層構造の中核
AssetはArea → Line → Equipmentの3階層ツリーを形成します。IDにタイプコードを含め、視覚的に階層を把握できるよう設計することを推奨します。
정규식: ^ASSET_[A-Z0-9_]+$
권장 형식: ASSET_<site-token>_<type-code>_<number>
Asset Typeコード
| asset_type値 | 意味 | 推奨IDパターン |
|---|---|---|
A | Area(区域) | ASSET_<site>_A_<number> |
L | Line(ライン) | ASSET_<site>_L_<number> |
M | Equipment(設備、Machine) | ASSET_<site>_M_<number> |
💡 EQUIPMENTコードが
Mである理由: Equipment = Machine。検索・フィルタリングで短く明確な1文字コードを使用します。
標準IDパターンの例
大田工場(SITE_DJ)の1番区域、その中の2番ライン、その上の3番設備:
ASSET_DJ_A_0001 ← Area (1구역)
└ ASSET_DJ_L_0002 ← Line (2번 라인)
└ ASSET_DJ_M_0003 ← Equipment (3번 설비)
例 — 資産ツリーの作成
import plantpulse.api.v5.dto.request.AssetRequestV5;
import plantpulse.api.v5.dto.response.AssetResponseV5;
// 1) 사이트 직속 Area
AssetRequestV5 area = new AssetRequestV5();
area.setSite_id("SITE_DJ");
area.setParent_asset_id("SITE_DJ"); // 부모는 사이트 ID
area.setAsset_id("ASSET_DJ_A_0001");
area.setAsset_name("조립구역");
area.setAsset_type("A");
client.asset().create(area);
// 2) Area 산하 Line
AssetRequestV5 line = new AssetRequestV5();
line.setSite_id("SITE_DJ");
line.setParent_asset_id("ASSET_DJ_A_0001"); // 부모는 Area
line.setAsset_id("ASSET_DJ_L_0001");
line.setAsset_name("1라인");
line.setAsset_type("L");
client.asset().create(line);
// 3) Line 산하 Equipment
AssetRequestV5 equip = new AssetRequestV5();
equip.setSite_id("SITE_DJ");
equip.setParent_asset_id("ASSET_DJ_L_0001"); // 부모는 Line
equip.setAsset_id("ASSET_DJ_M_0001");
equip.setAsset_name("CNC #1");
equip.setAsset_type("M");
equip.setTable_type("CNC");
client.asset().create(equip);
parent_asset_id規則
| 子タイプ | parent_asset_id値 |
|---|---|
Area (A) | サイトID(例: SITE_DJ) |
Line (L) | Areaのasset_id(例: ASSET_DJ_A_0001) |
Equipment (M) | Lineのasset_id(例: ASSET_DJ_L_0001) |
Equipmentの下にさらに下位のEquipmentを配置することもできます(サブアセンブリ)。その場合、parent_asset_idは上位Equipmentのasset_idです。
2.6 Tag ID
정규식: ^V*TAG_[A-Z0-9_]+$
허용: TAG_…, VTAG_…, VVTAG_… (V 누적 가능 — Virtual Tag 파생 단계)
Tagはデータポイント(センサ値、カウンタ、状態など)の定義です。OPCとは1:1、Assetとは0:N(任意の接続)の関係です。
推奨パターン
| シナリオ | パターン | 例 |
|---|---|---|
| OPC接続タグ | TAG_<part-of-opc-id>_<channel-no> | TAG_EDGE_00303_90007 |
| 独自定義タグ | TAG_<domain>_<number> | TAG_PROD_COUNT_001 |
| Virtual Tag(1段階) | VTAG_<purpose>_<number> | VTAG_OEE_LINE1 |
| Virtual Tag(2段階派生) | VVTAG_<purpose>_<number> | VVTAG_AGGREGATED_01 |
💡 Virtual Tagの
Vの累積: 計算式・集計タグの派生段階が深くなるほどVを追加します。通常はVTAG_の1段階で十分です。
例
import plantpulse.api.v5.dto.request.TagRequestV5;
TagRequestV5 req = new TagRequestV5();
req.setTag_id("TAG_EDGE_00303_90007");
req.setTag_name("Spindle RPM");
req.setOpc_id("OPC_EDGE_00303");
req.setSite_id("SITE_DJ");
req.setLinked_asset_id("ASSET_DJ_M_0001");
req.setJava_type("Double");
req.setUnit("RPM");
req.setTag_source("OPC");
req.setDescription("Spindle 회전수 (RPM)");
client.tag().create(req);
// Virtual Tag — 라인별 OEE 집계
TagRequestV5 vtag = new TagRequestV5();
vtag.setTag_id("VTAG_OEE_LINE1");
vtag.setTag_name("Line1 OEE");
vtag.setSite_id("SITE_DJ");
vtag.setTag_source("VIRTUAL");
client.tag().create(vtag);
tag_id vs tag_name vs alias_name
| フィールド | V5で変更可能か | 用途 |
|---|---|---|
tag_id | 変更不可(再作成を推奨) | システム内部の一意キー。不変 |
tag_name | update()またはpatchBasic() | ユーザーに表示される名前 |
alias_name | patchMetadata() | 外部システムとマッピングする別名(例: HMIタグ名) |
可能であれば
tag_idは不変とし、表示名はtag_name/alias_nameを使用することを推奨します。tag_idの変更は外部の時系列データとの整合性の問題を引き起こす可能性があります。
2.7 AlarmConfig / Employee / Customer / Product / Flow
これらのドメインもすべてサーバ検証が強制されます。正確な完全接頭辞を使用してください。
// Alarm Config
AlarmConfigRequestV5 alarm = new AlarmConfigRequestV5();
alarm.setAlarm_config_id("ALARM_CONFIG_TEMP_HIGH_01");
alarm.setSite_id("SITE_DJ");
// Employee
EmployeeRequestV5 emp = new EmployeeRequestV5();
emp.setEmployee_id("EMP_E12345");
emp.setRole_code("OPERATOR"); // OPERATOR, SUPERVISOR 등
// Customer — CUSTOMER_ (전체 단어, CUST_ 아님!)
CustomerRequestV5 cust = new CustomerRequestV5();
cust.setCustomer_id("CUSTOMER_001");
cust.setExternal_customer_id("ERP_C001");
// Product — PRODUCT_ (전체 단어, PROD_ 아님!)
ProductRequestV5 prod = new ProductRequestV5();
prod.setProduct_id("PRODUCT_A001");
prod.setProduct_code("SKU-A001");
// Flow
FlowRequestV5 flow = new FlowRequestV5();
flow.setFlow_id("FLOW_OEE_DAILY");
flow.setSite_id("SITE_DJ");
❌ よく発生する拒否事例
cust.setCustomer_id("CUST_001"); // ❌ CUST_ 아님 → E1002
prod.setProduct_id("PROD_A001"); // ❌ PROD_ 아님 → E1002
emp.setEmployee_id("E12345"); // ❌ EMP_ 누락 → E1002
flow.setFlow_id("flow_oee_daily"); // ❌ 소문자 → E1002
2.8 User ID(ログインアカウント)
정규식: ^[A-Z][A-Z0-9_]*$
규칙: 대문자로 시작, 이후 [A-Z0-9_]만 허용
他のドメインと異なり固定接頭辞がなく、先頭文字が大文字である必要があります。
✅ ADMIN
✅ OPERATOR_01
✅ KOPENS_USER
❌ admin → 소문자 시작
❌ 1USER → 숫자 시작
❌ _ADMIN → _ 시작
2.9 Calendar / Order — 検証なし
この2つのドメインはサーバ検証がないためID形式は自由です。ただし運用の一貫性と検索の利便性のため、推奨パターンに従ってください。
Calendar
import plantpulse.api.v5.dto.request.CalendarRequestV5;
CalendarRequestV5 cal = new CalendarRequestV5();
cal.setCalendar_id("CAL_20260514_0001"); // CAL_<YYYYMMDD>_<seq>
cal.setSite_id("SITE_DJ");
cal.setAsset_id("ASSET_DJ_M_0001");
cal.setTarget_type("MTN"); // 점검 일정
| target_type | 意味 |
|---|---|
MTN | 定期点検 (Maintenance) |
HOLIDAY | 休日/非稼働 |
INSPECTION | 検査 |
MEETING | 会議 |
Order
import plantpulse.api.v5.dto.request.OrderRequestV5;
OrderRequestV5 order = new OrderRequestV5();
order.setOrder_id("ORD_20260514_001"); // ORD_<YYYYMMDD>_<seq>
order.setSite_id("SITE_DJ");
order.setAsset_id("ASSET_DJ_M_0001");
order.setCustomer_id("CUSTOMER_001"); // CUSTOMER_ 주의!
order.setProduct_id("PRODUCT_A001"); // PRODUCT_ 주의!
order.setEmployee_id("EMP_E12345");
order.setTarget_units(500);
作業指示ステータス(ISA-88): WAIT → START → END / ABORTED (詳細はOrderサービス)
2.10 ID設計のベストプラクティス
推奨事項
- 不変性の維持 — 一度付与したIDは変更しないでください。変更が必要な場合は新しいIDへ移行することを推奨します。
- 階層をIDに表現 —
ASSET_<site>_<type>_<number>のように階層情報をIDに含めると運用時の可視性が向上します。 - 固定桁数の使用 — 番号部分は
0001、00001のようにパディングしてソート順を保ってください。 - 大文字・アンダースコアの統一 — システム全体で大文字小文字の混用を避け、
[A-Z0-9_]パターンを維持します。 - 外部システムIDは別フィールドへ — ERP/MESの元IDは
external_*_idフィールドに保管し、PlantPulse IDは独自体系を維持してください。
避けるべきパターン
- ❌ ハングル、空白、特殊文字の使用 —
ASSET_라인1,OPC 001 - ❌ 短すぎる、または意味のないID —
S1,A,T01 - ❌ 接頭辞の欠落または誤った略語 —
CUST_001(正解:CUSTOMER_001)、PROD_A001(正解:PRODUCT_A001) - ❌ 意味がIDに埋め込まれて変更できない —
ASSET_DJ_L_OLD_BROKEN_LINE
2.11 検証失敗レスポンスの確認
V5は検証失敗時、メソッドがnull(またはfalse)を返します。詳細なエラーはenvelopeで確認できます。
import plantpulse.api.v5.service.BaseServiceV5;
import plantpulse.json.JSONObject;
// V5 서비스 내부는 envelope를 외부에 노출하지 않으나,
// 디버그 모드를 켜면 로그에 출력됩니다.
client = new APIClient_V5(proto, host, port, user, token, true); // debug=true
レスポンスenvelopeの例:
{
"_status": "ERROR",
"_code": "E1002",
"_message": "validation failed: site_id must match ^V?SITE_[A-Z0-9_]+$",
"_http_status": 400
}
詳細なエラーコードはレスポンス形式とエラー処理を参照してください。
次のステップ
- レスポンス形式とエラー処理 — エラーコードのマッピング
- Siteサービス — サイト作成から開始
- Assetサービス — 資産ツリーの構築
- Tagサービス — データポイントの定義