OPC UA for PackML をソースとしたデータ利活用のための基礎知識

概要
OPC UA for PackML に基づき生成したデータにてデータ利活用を行うために必要となる基礎的な知識を整理する。
注意事項
- 情報が古い可能性があります
- 内容が間違っている可能性があります。

OPC UA for PackML とは
OPC UA for PackML(OPC 30050)は、包装機械標準である PackML(Packaging Machine Language)を OPC UA の情報モデルに落とし込んだ標準仕様です。PackML のステートマシンやコマンド、稼働変数を PackMLBaseObjectType などの ObjectType として定義し、機種/ベンダーを超えて統一されたタグ構造と意味論を提供しています。これによりライン統合や MES/クラウド解析でマシン状態・生産データを標準化された OPC UA 通信で取得でき、独自タグ乱立やスキーマレス運用などのデータ品質に関する課題を解消できます。
PackML におけるが目的には下記があることが明記されています。
• Define a standard state-based model for automated machines.
• Identify definitions for common terminology.
• Explain to practitioners how to use state programming for automated machines.
• Provide references to actual implementation examples and templates from automation and > • control vendors.
• Identify a common tag structure for automated machines in order to:
• Provide for “connect & pack” functionality
• Provide functional interoperability and a consistent look and feel across the plant floor.
• Provide consistent tag structure for connection to plant MES and enterprise systems.
出所:PackML - Packaging Control - 4 Concept
• 自動マシンの標準的な状態ベース モデルを定義します。
• 一般的な用語の定義を特定する。
• 自動化されたマシンの状態プログラミングの使用方法を実務家に説明します。
• 実際の実装例と、オートメーションおよび制御ベンダーのテンプレートへの参照を提供します。
• 自動化マシンに共通するタグ構造を特定すると、以下のことが可能になります。
• 「connect & pack」機能の提供
• 機能的な相互運用性と、プラントフロア全体で一貫したルックアンドフィールを提供します。
• プラント、MES、エンタープライズシステムへの接続に一貫したタグ構造を提供します。
上記の翻訳
PackML では下記が提供されることが明記されています。
• Standard defined machine states and operational flow
• Overall Equipment Effectiveness (OEE) data
• Root Cause Analysis (RCA) data
• Flexible recipe schemes and common SCADA or MES inputs
出所:PackML - Packaging Control - 4 Concept
• 標準で定義された機械の状態と運用フロー
• 総合設備効率(OEE)データ
• 根本原因分析(RCA)データ
• 柔軟なレシピスキームと共通のSCADAまたはMES入力
上記の翻訳
OPC UA for PackML は OPC Foundationにより OPC 30050 という仕様番号が付与されています。Released 1.01 が最新版であり、下記のサイトにて公開されています。
PackML 導入時に重要なことは、 state や状態遷移を理解して活用することです。下記図に示されているように PackML では標準化がされており、ベンダーに依存せずにライン全体で統一したLook & Feel
を持つことが可能となりま。そのことにより、生成されたデータに対するデータ分析方法の共通化を実施につながります。
引用元:PackML - Packaging Control - 6 PackML Data Representation Model

参考になったコンテンツ
OPC UA for PackML のドキュメント
YouTube の動画
- 【OPC Day Japan 2023】OPC-UA/PackMLを活用した包装機械のIoT化の紹介と、業界標準策定に向けた活動
- 【OPC Day Japan 2023】複雑化する製造業のデータ活用を支える標準化―OPC UA for PackMLについてー

OPC UA for PackML のデータを活用するために
OPC UA for PackML を活用する
OPC UA for PackML を活用するためには、OPC UA for PackML に準拠させるだけでなく、 5つのステップを継続的に実施することが重要です。どこか 1 ステップでも標準やベストプラクティスから外れると後工程の手戻りや活用の阻害要因となる可能性があります。以下の表は各ステップの目的・代表的な標準/技術・典型的な失敗例を整理したものです。
# | ステップ | 目的 | 失敗例 |
---|---|---|---|
1 | 生成 | デバイスから相互運用性を考慮したデータの生成をを実施 | 共通タグの導入を優先せずに、独自タグ名や状態を追加すること |
2 | 提供 | エッジで単位・階層・意味付けを行った最適なモデルに基づいたデータをの提供を実施 | 単位・ライン階層を付与せずスキーマレス配信をデータモデリングを適切に実施しないこと |
3 | 蓄積 | レイテンシーとコストから最適なデータ連携・蓄積を実施 | リアルタイム処理を優先してしまいコストの問題に直面 |
4 | 活用 | 可視化・解析によりデータ活用の実施 | データ利活用のダッシュボードのみで実施し、活用の幅を広げないこと |
5 | 改善 | 業務改善の実施 | システム導入のみが目的となってしまい業務プロセスに落とし込めないこと |
インスタンスアドレス空間
出所:PackML - Packaging Control - 4.1 Overview
PackMLBaseObjectTypeのインスタンスとして、OPC 定義の Objects フォルダーの下に PackMLObjects フォルダー配下に1つ以上含める必要があります。
出所:PackML - Packaging Control - 6 PackML Data Representation Model
クラスを整理すると下記のようになります。

PackMLBaseObjectType
PackMLBaseObjectType は下記の項目により構成されています。
出所:PackML - Packaging Control - 6.3.2 PackMLBaseObjectType
json で表現すると下記のようになるようです。
{
"TagID": "TokyoPlant.Filling.Line01.UnitA",
"PackMLVersion": "1.01",
"Admin": {},
"Status": {},
"BaseStateMachine": {},
"UnitMode": {
"RequestedMode": 1,
"Timestamp": "2025-06-05T00:03:00+09:00"
},
"SetMachSpeed": {
"TargetSpeed": 320.0,
"Unit": "bpm",
"RampTimeSec": 5
},
"SetProduct": {
"Product": [
{
"Id": 501,
"Name": "Shampoo250ml",
"Version": "v3.2",
"TargetWeightKg": 0.25
}
]
},
"SetParameter": {
"Parameters": [
{
"Id": 102,
"Value": 1.35
},
{
"Id": 205,
"Value": 42
}
]
},
"RemoteCommand": {
"Command": "StartCIP",
"Arguments": {
"Cycle": 1,
"Chemical": "NaOH2%"
}
},
"SetInterlock": {
"InterlockId": 15,
"State": false
}
}

PackMLAdminObjectType
下記の項目により構成されています。
出所:PackML - Packaging Control - 6.3.4 PackMLAdminObjectType
json で表現すると下記のようになるようです。
{
"Admin": {
"Parameter": [
{
"Id": 101,
"Name": "FoilThickness",
"Unit": "µm",
"Value": 18.0
}
],
"ParameterExtent": 32,
"Alarm": [
{
"Id": 9001,
"Timestamp": "2025-06-05T00:05:12+09:00",
"Severity": "Error",
"Description": "Emergency-Stop"
}
],
"AlarmExtent": 64,
"AlarmHistory": [
{
"Id": 8997,
"Timestamp": "2025-06-04T20:17:50+09:00",
"Severity": "Warning",
"Description": "Low Air Pressure"
}
],
"AlarmHistoryExtent": 256,
"Warning": [
{
"Id": 3001,
"Timestamp": "2025-06-05T00:04:30+09:00",
"Description": "Lubricant Level Low"
}
],
"WarningExtent": 32,
"StopReason": [
{
"Id": 7001,
"Timestamp": "2025-06-04T18:02:44+09:00",
"Description": "Material Jam"
}
],
"StopReasonExtent": 16,
"ProdConsumedCount": [
{
"MaterialId": "Bottle_250ml",
"Count": 720
}
],
"ProdProcessedCount": [
{
"ProductId": "Shampoo-250ml",
"Count": 710
}
],
"ProdDefectiveCount": [
{
"ProductId": "Shampoo-250ml",
"Count": 10
}
],
"MachDesignSpeed": 350.0,
"ModeCurrentTime": [
180,
],
"ModeCumulativeTime": [
86400,
],
"StateCurrentTime": [
[
30,
10,
0,
]
],
"StateCumulativeTime": [
[
6000,
250,
0
]
],
"AccTimeSinceReset": 93600
}
}

PackMLStatusObjectType
下記の項目により構成されています。
出所:PackML - Packaging Control - 6.3.3 PackMLStatusObjectType
json で表現すると下記のようになるようです。
{
"Status": {
"UnitModeRequested": false,
"UnitSupportedModes": "ns=1;i=5001",
"UnitModeCurrent": 0,
"UnitModeChangeInProcess": false,
"StateRequested": 0,
"StateChangeInProcess": false,
"MachSpeed": 320.0,
"CurMachSpeed": 318.5,
"EquipmentBlocked": false,
"EquipmentStarved": true,
"MaterialInterlocked": false,
"MaterialInterlock": [
true
],
"Parameter": [
{
"Id": 102,
"Name": "TargetWeight",
"Unit": "kg",
"Value": 1.25
}
],
"RemoteParameter": [
{
"Id": 201,
"Name": "TemperatureSetpoint",
"Value": 65.0
}
],
"Product": [
{
"Id": 501,
"Name": "Shampoo250ml",
"Version": "v3.2"
}
]
}
}

PackMLBaseStateMachineType
下記の項目により構成されています。
出所:PackML - Packaging Control - 6.3.6 PackMLBaseStateMachineType
json で表現すると下記のようになるようです。
{
"BaseStateMachine": {
"CurrentState": "Cleared",
"LastTransition": "AbortedToCleared",
"AvailableStates": [
{
"BrowseName": "Clearing",
"NodeId": "ns=1;i=11001",
"StateNumber": 1
},
{
"BrowseName": "Stopped",
"NodeId": "ns=1;i=11002",
"StateNumber": 2
},
{
"BrowseName": "Stopping",
"NodeId": "ns=1;i=11007",
"StateNumber": 7
},
{
"BrowseName": "Running",
"NodeId": "ns=1;i=11018",
"StateNumber": 18
},
{
"BrowseName": "Aborting",
"NodeId": "ns=1;i=10108",
"StateNumber": 8
},
{
"BrowseName": "Aborted",
"NodeId": "ns=1;i=10109",
"StateNumber": 9
},
{
"BrowseName": "Cleared",
"NodeId": "ns=1;i=10119",
"StateNumber": 19
}
],
"AvailableTransitions": [
{
"BrowseName": "AbortedToCleared",
"NodeId": "ns=1;i=20103"
},
{
"BrowseName": "ClearedToAborting",
"NodeId": "ns=1;i=20101"
},
{
"BrowseName": "AbortingToAborted",
"NodeId": "ns=1;i=20102"
}
],
"Aborting": {
"StateNumber": 8
},
"Aborted": {
"StateNumber": 9
},
"Cleared": {
"StateNumber": 19
},
"MachineState": {
"CurrentState": "Stopped",
"LastTransition": "ClearingToStopped",
"AvailableStates": [
{
"BrowseName": "Clearing",
"NodeId": "ns=1;i=11001",
"StateNumber": 1
},
{
"BrowseName": "Stopped",
"NodeId": "ns=1;i=11002",
"StateNumber": 2
},
{
"BrowseName": "Stopping",
"NodeId": "ns=1;i=11007",
"StateNumber": 7
},
{
"BrowseName": "Running",
"NodeId": "ns=1;i=11018",
"StateNumber": 18
}
],
"AvailableTransitions": [
{
"BrowseName": "ClearingToStopped",
"NodeId": "ns=1;i=21004"
},
{
"BrowseName": "StoppedToRunning",
"NodeId": "ns=1;i=21001"
},
{
"BrowseName": "RunningToStopping",
"NodeId": "ns=1;i=21002"
},
{
"BrowseName": "StoppingToStopped",
"NodeId": "ns=1;i=21003"
}
],
"Stopped": {
"StateNumber": 2
},
"Stopping": {
"StateNumber": 7
},
"Clearing": {
"StateNumber": 1
},
"Running": {
"StateNumber": 18
},
"ExecuteState": {
"CurrentState": "Idle",
"AvailableStates": [
{
"BrowseName": "Idle",
"StateNumber": 4
},
{
"BrowseName": "Starting",
"StateNumber": 3
},
{
"BrowseName": "Execute",
"StateNumber": 6
},
{
"BrowseName": "Complete",
"StateNumber": 17
}
],
"Idle": {
"StateNumber": 4
},
"Starting": {
"StateNumber": 3
},
"Execute": {
"StateNumber": 6
},
"Complete": {
"StateNumber": 17
},
"Methods": {
"Start": {
"Executable": true
},
"ToComplete": {
"Executable": true
}
}
},
"Methods": {
"Stop": {
"Executable": true
},
"Reset": {
"Executable": true
}
}
},
"AbortedToCleared": {
"FromState": "Aborted",
"ToState": "Cleared",
"Trigger": "Clear"
},
"AbortingToAborted": {
"FromState": "Aborting",
"ToState": "Aborted",
"Trigger": "AbortComplete"
},
"ClearedToAborting": {
"FromState": "Cleared",
"ToState": "Aborting",
"Trigger": "Abort"
},
"Methods": {
"Abort": {
"Executable": true
},
"Clear": {
"Executable": true
}
}
}
}

データの全体
{
"TagID": "TokyoPlant.Filling.Line01.UnitA",
"PackMLVersion": "1.01",
"Admin": {
"Parameter": [
{
"Id": 101,
"Name": "FoilThickness",
"Unit": "µm",
"Value": 18.0
}
],
"ParameterExtent": 32,
"Alarm": [
{
"Id": 9001,
"Timestamp": "2025-06-05T00:05:12+09:00",
"Severity": "Error",
"Description": "Emergency-Stop"
}
],
"AlarmExtent": 64,
"AlarmHistory": [
{
"Id": 8997,
"Timestamp": "2025-06-04T20:17:50+09:00",
"Severity": "Warning",
"Description": "Low Air Pressure"
}
],
"AlarmHistoryExtent": 256,
"Warning": [
{
"Id": 3001,
"Timestamp": "2025-06-05T00:04:30+09:00",
"Description": "Lubricant Level Low"
}
],
"WarningExtent": 32,
"StopReason": [
{
"Id": 7001,
"Timestamp": "2025-06-04T18:02:44+09:00",
"Description": "Material Jam"
}
],
"StopReasonExtent": 16,
"ProdConsumedCount": [
{
"MaterialId": "Bottle_250ml",
"Count": 720
}
],
"ProdProcessedCount": [
{
"ProductId": "Shampoo-250ml",
"Count": 710
}
],
"ProdDefectiveCount": [
{
"ProductId": "Shampoo-250ml",
"Count": 10
}
],
"MachDesignSpeed": 350.0,
"ModeCurrentTime": [
180
],
"ModeCumulativeTime": [
86400
],
"StateCurrentTime": [
[
30,
10
]
],
"StateCumulativeTime": [
[
6000,
250
]
],
"AccTimeSinceReset": 93600
},
"Status": {
"UnitModeRequested": false,
"UnitSupportedModes": "ns=1;i=5001",
"UnitModeCurrent": 0,
"UnitModeChangeInProcess": false,
"StateRequested": 0,
"StateChangeInProcess": false,
"MachSpeed": 320.0,
"CurMachSpeed": 318.5,
"EquipmentBlocked": false,
"EquipmentStarved": true,
"MaterialInterlocked": false,
"MaterialInterlock": [
true
],
"Parameter": [
{
"Id": 102,
"Name": "TargetWeight",
"Unit": "kg",
"Value": 1.25
}
],
"RemoteParameter": [
{
"Id": 201,
"Name": "TemperatureSetpoint",
"Value": 65.0
}
],
"Product": [
{
"Id": 501,
"Name": "Shampoo250ml",
"Version": "v3.2"
}
]
},
"BaseStateMachine": {
"CurrentState": "Cleared",
"LastTransition": "AbortedToCleared",
"AvailableStates": [
{
"BrowseName": "Clearing",
"NodeId": "ns=1;i=11001",
"StateNumber": 1
},
{
"BrowseName": "Stopped",
"NodeId": "ns=1;i=11002",
"StateNumber": 2
},
{
"BrowseName": "Stopping",
"NodeId": "ns=1;i=11007",
"StateNumber": 7
},
{
"BrowseName": "Running",
"NodeId": "ns=1;i=11018",
"StateNumber": 18
},
{
"BrowseName": "Aborting",
"NodeId": "ns=1;i=10108",
"StateNumber": 8
},
{
"BrowseName": "Aborted",
"NodeId": "ns=1;i=10109",
"StateNumber": 9
},
{
"BrowseName": "Cleared",
"NodeId": "ns=1;i=10119",
"StateNumber": 19
}
],
"AvailableTransitions": [
{
"BrowseName": "AbortedToCleared",
"NodeId": "ns=1;i=20103"
},
{
"BrowseName": "ClearedToAborting",
"NodeId": "ns=1;i=20101"
},
{
"BrowseName": "AbortingToAborted",
"NodeId": "ns=1;i=20102"
}
],
"Aborting": {
"StateNumber": 8
},
"Aborted": {
"StateNumber": 9
},
"Cleared": {
"StateNumber": 19
},
"MachineState": {
"CurrentState": "Stopped",
"LastTransition": "ClearingToStopped",
"AvailableStates": [
{
"BrowseName": "Clearing",
"NodeId": "ns=1;i=11001",
"StateNumber": 1
},
{
"BrowseName": "Stopped",
"NodeId": "ns=1;i=11002",
"StateNumber": 2
},
{
"BrowseName": "Stopping",
"NodeId": "ns=1;i=11007",
"StateNumber": 7
},
{
"BrowseName": "Running",
"NodeId": "ns=1;i=11018",
"StateNumber": 18
}
],
"AvailableTransitions": [
{
"BrowseName": "ClearingToStopped",
"NodeId": "ns=1;i=21004"
},
{
"BrowseName": "StoppedToRunning",
"NodeId": "ns=1;i=21001"
},
{
"BrowseName": "RunningToStopping",
"NodeId": "ns=1;i=21002"
},
{
"BrowseName": "StoppingToStopped",
"NodeId": "ns=1;i=21003"
}
],
"Stopped": {
"StateNumber": 2
},
"Stopping": {
"StateNumber": 7
},
"Clearing": {
"StateNumber": 1
},
"Running": {
"StateNumber": 18
},
"ExecuteState": {
"CurrentState": "Idle",
"AvailableStates": [
{
"BrowseName": "Idle",
"StateNumber": 4
},
{
"BrowseName": "Starting",
"StateNumber": 3
},
{
"BrowseName": "Execute",
"StateNumber": 6
},
{
"BrowseName": "Complete",
"StateNumber": 17
}
],
"Idle": {
"StateNumber": 4
},
"Starting": {
"StateNumber": 3
},
"Execute": {
"StateNumber": 6
},
"Complete": {
"StateNumber": 17
},
"Methods": {
"Start": {
"Executable": true
},
"ToComplete": {
"Executable": true
}
}
},
"Methods": {
"Stop": {
"Executable": true
},
"Reset": {
"Executable": true
}
}
},
"AbortedToCleared": {
"FromState": "Aborted",
"ToState": "Cleared",
"Trigger": "Clear"
},
"AbortingToAborted": {
"FromState": "Aborting",
"ToState": "Aborted",
"Trigger": "AbortComplete"
},
"ClearedToAborting": {
"FromState": "Cleared",
"ToState": "Aborting",
"Trigger": "Abort"
},
"Methods": {
"Abort": {
"Executable": true
},
"Clear": {
"Executable": true
}
}
},
"UnitMode": {
"RequestedMode": 1,
"Timestamp": "2025-06-05T00:03:00+09:00"
},
"SetMachSpeed": {
"TargetSpeed": 320.0,
"Unit": "bpm",
"RampTimeSec": 5
},
"SetProduct": {
"Product": [
{
"Id": 501,
"Name": "Shampoo250ml",
"Version": "v3.2",
"TargetWeightKg": 0.25
}
]
},
"SetParameter": {
"Parameters": [
{
"Id": 102,
"Value": 1.35
},
{
"Id": 205,
"Value": 42
}
]
},
"RemoteCommand": {
"Command": "StartCIP",
"Arguments": {
"Cycle": 1,
"Chemical": "NaOH2%"
}
},
"SetInterlock": {
"InterlockId": 15,
"State": false
}
}