OPC-UA ドライバ
概要
OPC Unified Architecture (IEC 62541) ベースの産業データ標準プロトコル。
| 項目 | 値 |
|---|---|
opc_type | OPCUA |
| 実装クラス | plantpulse.driver.protocol.opcua.OPCUA_34_Driver |
| ライブラリ | Eclipse Milo (milo-sdk-client) |
| read | ✅ |
| write | ✅ (node.writeValue) |
| セキュリティ | ユーザー認証 Anonymous, Username/Password. チャネルセキュリティ None · Sign · SignAndEncrypt · auto |
Kepware, Matrikon, Prosys など大部分の OPC-UA サーバーと互換性があります。
OPC 登録フォーム
| フィールド | 意味 | 例 |
|---|---|---|
opc_agent_ip | OPC-UA サーバー IP | 192.168.0.40 |
opc_agent_port | OPC-UA サーバー TCP ポート | 49320 (Kepware デフォルト) |
timecycle | ポーリング周期 (ms) | 1000 |
options.servername | endpoint 末尾のサーバー名 | (Kepware の場合は空欄) |
options.username | 認証ユーザー | kopens |
options.password | 認証パスワード | *** |
options.discovery | true の場合、connect 時に RootFolder からノードツリー全体をブラウジングしてログに記録 (エンドポイント検索ではない — エンドポイントは画面の [エンドポイント照会]) | false (推奨) |
options.security_mode | チャネルセキュリティモード。 None(デフォルト) · Sign · SignAndEncrypt · auto(Sign·SignAndEncrypt のうち最も強力なもの)。 None でなければ None には下げない。大文字小文字を区別せず、不明な値は OPCUA_SECURITY_CONFIG_INVALID | SignAndEncrypt |
options.security_policy | auto(デフォルト) · Basic256Sha256 · Aes128_Sha256_RsaOaep · Aes256_Sha256_RsaPss。 auto は Aes256_Sha256_RsaPss > Basic256Sha256 > Aes128_Sha256_RsaOaep の順。セキュリティモードが None の場合は無視 | auto |
options.allow_deprecated_policy | true の場合、廃止された Basic256 · Basic128Rsa15 も許容(auto 候補に含まれ明示も可能)。 true/false 以外の値は OPCUA_SECURITY_CONFIG_INVALID | false |
生成される endpoint URL 形式:
opc.tcp://<opc_agent_ip>:<opc_agent_port>/<servername>
username + password が両方あれば UsernameProvider、なければ AnonymousProvider を使用。
pki_dir(クライアント証明書と信頼リストディレクトリ)は入力欄ではありません。edge-web がセキュリティモード None 以外のときだけ $PE_DATA_DIR/pp-data/opcua-client を挿入し、接続行に保存された値は破棄します。
エンドポイント選択:
security_mode=None(OPCUA_34_Driver.selectEndpoint) — サーバーが広告したリストからMessageSecurityMode.Noneであるものだけ を選択します。使用するトークン種類(UserName / Anonymous)を広告したエンドポイントが優先され、なければ最初の None エンドポイントとなります。- その他のモード (
OpcuaEndpointSelector.selectSecure) — 受け入れ可能なモード・ポリシーと使用するトークン種類をすべて満たすエンドポイントの中から、最も強力なものを選択します。なければ None には下げずOPCUA_NO_MATCHING_ENDPOINTとして失敗します。
選択したエンドポイント URL のホストは opc_agent_ip に変更します(ポート・パスはサーバーが広告した値)。原因が判明している失敗(証明書 · セキュリティ設定 · 適合するエンドポイントなし)は OPCUA connect refused: error_code=<코드> opc_id=<OPC ID> ... WARN が一行残ります(同一原因の場合は一度のみ)。 OPCUA_CONNECT_FAILED · OPCUA_PKI_ERROR は毎回 OPCUA connect failed: ... ERROR とスタックトレースが残ります。
サーバー証明書の信頼、エッジ証明書のダウンロード、エラー文言は OPC-UA 接続 — セキュリティ接続 にあります。初めて見るサーバー証明書は拒否され(初回接続時の自動信頼なし)、管理者が画面で信頼した後に接続されます。
タグ plc_address 形式
OPC-UA 標準 NodeId 表記。例:
| 表記 | 意味 |
|---|---|
ns=2;s=Simulator.Sine1 | namespace 2, string identifier Simulator.Sine1 |
ns=2;i=1234 | numeric identifier 1234 |
ns=3;g=09087e75-8e5e-499b-954f-f2a8624db28a | GUID identifier |
ns=2;b=Mb= | opaque (bytestring) identifier |
Kepware の場合は通常 ns=2;s=<Channel>.<Device>.<Tag> 形式。
data_type / format マッピング
OPC-UA 変数ノードの Value を String にキャストして返します。 data_type は後続段階
(PLCValueFomula, Sparkplug 発行など) がキャストに使用します。
data_type | 動作 |
|---|---|
Float / Double | 数値のまま |
Int / Integer / Int32 / Short / Long | 数値のまま |
Boolean / Bool | true/false 文字列 |
String / Text | UTF-8 文字列 |
DateTime | ISO 文字列 |
format は OPC-UA では一般的に使用しません。後処理の計算式が必要な場合は fomula を使用。
よくあるエラー + 対処法
| メッセージ / 症状 | 原因 | 対処法 |
|---|---|---|
connection refused | サーバー未稼働、ポート遮断 | telnet <ip> <port> で通信確認 |
Bad_UserAccessDenied | username/password 誤り、匿名接続不可 | サーバー側でユーザー登録または anonymous を有効化 |
OPCUA_CLIENT_CERT_REJECTED (Bad_SecurityChecksFailed など) | サーバーがエッジクライアント証明書を信頼していない | エッジ証明書(.der)をサーバーの信頼リストに追加 |
OPCUA_NO_MATCHING_ENDPOINT | サーバーがそのモード・ポリシー・トークンのエンドポイントを広告していない | 画面の [エンドポイント照会] でサーバーが提示する組み合わせを確認し、それに合わせる |
| ポート不一致による接続失敗 | ドライバは広告されたエンドポイントのホストのみを opc_agent_ip に変更し、ポート・パスはそのまま使用する | NAT・ポートフォワーディングでポートを変更して公開している場合は、サーバーが広告するポートと一致させる。hosts マッピングは不要 |
| 値が常に 0 / null | NodeId の誤記、namespace 番号の不一致 | UA Expert などのクライアントで同一 NodeId の read を検証 |
curl 登録例
curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_UA_Kepware",
"opc_type": "OPCUA",
"opc_name": "Kepware",
"opc_agent_ip": "192.168.0.40",
"opc_agent_port": "49320",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": {
"username": "kopens",
"password": "***",
"discovery": "false"
},
"tag_list": [
{
"tag_id": "OPC_UA_Kepware_TAG_00001",
"tag_name": "Sine1",
"plc_address": "ns=2;s=Simulator.Sine1",
"data_type": "Float",
"description": "Sine wave"
},
{
"tag_id": "OPC_UA_Kepware_TAG_00002",
"tag_name": "Random1",
"plc_address": "ns=2;s=Simulator.Random1",
"data_type": "Integer"
}
]
}'
値 read:
curl -s http://<edge-host>/api/v1/tag/OPC_UA_Kepware_TAG_00001/value | jq
参考: Kepware クイック設定ガイド
- Kepware Server → Project → チャネル追加 (例:
Simulator)。 - デバイス追加 (例:
Simulator) → モデル =16 Bit Device。 - タグ追加 →
Sine1, typeFloat, scan rate100msなど。 Project Properties → OPC UA → Server Endpointでポート49320を有効化。- Anonymous またはユーザーアカウントを有効化。セキュリティ接続の場合はエンドポイントセキュリティポリシーで
Basic256Sha256以上と Sign and Encrypt を有効にし、エッジ証明書を信頼リストに追加。
→ Edge 登録フォーム:
| フィールド | 値 |
|---|---|
| opc_agent_ip | Kepware サーバー IP |
| opc_agent_port | 49320 |
| options.servername | (空欄) |
| options.username/password | 上記で作成したアカウント |
| plc_address | ns=2;s=Simulator.Simulator.Sine1 |
例集 (データタイプ別)
OPC-UA は変数ノードの値(Variant)を String にキャストして返します。 data_type は後処理 (PLCValueFomula, Sparkplug DataTypeMapper) がキャストに使用。 format は一般的に使用しません。
Boolean
data_type | plc_address 例 | 備考 |
|---|---|---|
Boolean | ns=2;s=Simulator.Boolean1 | Kepware Simulator の Boolean タグ |
Boolean | ns=2;s=PLC.Status.Running | Kepware Channel.Device.Tag |
Boolean | ns=2;i=1003 | numeric NodeId |
16/32-bit 整数
data_type | plc_address 例 | 備考 |
|---|---|---|
Integer | ns=2;s=Simulator.Random1 | Random integer シミュレーション |
Integer | ns=2;s=Simulator.Counter1 | カウンタ |
Integer | ns=2;s=PLC.D100 | Kepware MELSEC チャネル露出 |
64-bit 整数
data_type | plc_address 例 | 備考 |
|---|---|---|
Long | ns=2;s=Simulator.LongCounter | UInt64 / Int64 ノード |
Long | ns=2;s=PLC.Cycle.Total | 累積カウンタ |
浮動小数点数
data_type | plc_address 例 | 備考 |
|---|---|---|
Float | ns=2;s=Simulator.Sine1 | sine wave シミュレーション |
Float | ns=2;s=Simulator.Ramp1 | ramp wave |
Double | ns=2;s=PLC.Pressure | 精密測定値 |
文字列
data_type | plc_address 例 | 備考 |
|---|---|---|
String | ns=2;s=Simulator.User1.Name | 文字列ノード |
String | ns=2;s=PLC.Recipe.Active | レシピ名 |
NodeId 形式別
| identifier タイプ | plc_address 例 |
|---|---|
String (s=) | ns=2;s=Simulator.Sine1 |
Numeric (i=) | ns=2;i=1234 |
GUID (g=) | ns=3;g=09087e75-8e5e-499b-954f-f2a8624db28a |
Opaque (b=) | ns=2;b=Mb= |
計算式活用
| 用途 | data_type | fomula | 備考 |
|---|---|---|---|
| 単位変換 | Float | ${VALUE}*0.001 | g → kg など |
| ゼロ点補正 | Float | ${VALUE}-${TAG_ZERO} | 他の OPCUA タグを参照可能 |
| 型変換 | Float | ${VALUE}*1.0 | Integer → Float 強制 |
| 多項式 | Float | ${VALUE}*${VALUE}*0.0001 | 非線形 |
curl 総合例 (全タイプ)
curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_UA_FULL",
"opc_type": "OPCUA",
"opc_name": "Kepware Full",
"opc_agent_ip": "192.168.0.40",
"opc_agent_port": "49320",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": { "discovery": "false" },
"tag_list": [
{"tag_id":"OPC_UA_FULL_T01", "tag_name":"BoolTag", "plc_address":"ns=2;s=Simulator.Boolean1", "data_type":"Boolean"},
{"tag_id":"OPC_UA_FULL_T02", "tag_name":"IntTag", "plc_address":"ns=2;s=Simulator.Random1", "data_type":"Integer"},
{"tag_id":"OPC_UA_FULL_T03", "tag_name":"LongTag", "plc_address":"ns=2;s=Simulator.LongCounter", "data_type":"Long"},
{"tag_id":"OPC_UA_FULL_T04", "tag_name":"FloatTag", "plc_address":"ns=2;s=Simulator.Sine1", "data_type":"Float"},
{"tag_id":"OPC_UA_FULL_T05", "tag_name":"DoubleTag", "plc_address":"ns=2;s=PLC.Pressure", "data_type":"Double"},
{"tag_id":"OPC_UA_FULL_T06", "tag_name":"StringTag", "plc_address":"ns=2;s=Simulator.User1.Name", "data_type":"String"},
{"tag_id":"OPC_UA_FULL_T07", "tag_name":"NumIdTag", "plc_address":"ns=2;i=1234", "data_type":"Integer"},
{"tag_id":"OPC_UA_FULL_T08", "tag_name":"ScaledTag", "plc_address":"ns=2;s=Simulator.Sine1", "data_type":"Float", "fomula":"${VALUE}*100"}
]
}'