IoTプロトコル

OPC UA

産業機器の標準データ連携規格。

概要

OPC UA(OPC Unified Architecture)は、産業オートメーション向けに設計されたオープンな通信規格・データモデル標準です。OPC Foundationが2008年に策定し(IEC 62541として国際標準化)、製造業・エネルギー・プロセス産業などにおけるデバイス間・システム間のデータ連携を目的としています。

従来のOPC(OLE for Process Control)がWindowsのCOM/DComponentモデルに依存していたのに対し、OPC UAはプラットフォームに依存しない(プラットフォーム非依存)設計となっており、LinuxやRTOS上でも動作します。通信プロトコル・セキュリティ・情報モデルを一体で定義している点が特徴で、単なる通信プロトコルではなく「産業データの意味論的な記述方法」も提供します。

OPC UAの主要な特徴は以下の通りです。

  • プラットフォーム非依存:Windows/Linux/RTOS上で動作
  • セキュリティ内包:認証・認可・暗号化を規格レベルで定義
  • 情報モデル:データに意味論(セマンティクス)を付与するアドレス空間モデル
  • スケーラブル:PLC・センサーからクラウドまで同一規格で接続
  • 信頼性:セッション管理・サブスクリプションによる確実なデータ配信

歴史・背景

OPCからOPC UAへ

1996年に策定された従来のOPC(Classic OPC)はWindowsのCOM/DCOMに依存しており、以下の問題がありました。

  • Windowsにしか対応できない
  • ファイアウォール越えが困難(DCOMのポートが動的)
  • セキュリティが脆弱
  • 組み込み機器への搭載が事実上不可能

これらを解決するためOPC UAが2008年に策定されました。2016年以降は**Industrie 4.0(ドイツ)IIoT(Industrial Internet of Things)**の基盤プロトコルとして注目が高まり、SiemensやGE、Beckhoffといった主要産業機器メーカーが製品に実装し始めました。

2018年にはMQTT上でOPC UAデータモデルを運ぶOPC UA Pub/Subが仕様に追加され、クラウドとの統合もよりシームレスになっています。


技術仕様

アドレス空間(Address Space)とノード

OPC UAの核心はアドレス空間と呼ばれる情報モデルです。すべてのデータは「ノード」として階層的に表現され、ノードIDで一意に識別されます。

Root
├── Objects
│   ├── Server
│   └── Factory
│       ├── Line1
│       │   ├── Machine001
│       │   │   ├── Temperature (Variable, ns=2;i=1001)
│       │   │   ├── Pressure    (Variable, ns=2;i=1002)
│       │   │   └── StartMotor  (Method,   ns=2;i=1003)
│       │   └── Machine002
│       └── Line2
├── Types
│   ├── ObjectTypes
│   ├── VariableTypes
│   └── DataTypes
└── Views

ノードクラス

ノードクラス説明
Object物理/論理エンティティ機械、センサー
Variableデータ値温度、圧力
Method呼び出し可能な操作モーター起動
DataTypeデータ型定義構造体、列挙型
ObjectTypeオブジェクトの型定義ポンプ型
ReferenceTypeノード間関係の種類HasComponent等

通信モデル

OPC UAは2種類の通信モデルを持ちます。

クライアント/サーバーモデル(従来型)

サービス説明
Read変数値の読み取り
Write変数値の書き込み
Browseアドレス空間の探索
Subscribe値変化の監視(Subscription)
CallMethodの呼び出し
TranslateパスからNodeIDへの変換

Pub/Subモデル(2018年追加)

MQTT、AMQP、UDP上でOPC UAデータを非同期配信します。クライアント/サーバーのようなコネクション管理が不要で、IoTクラウドへの統合に向いています。

[PLC(OPC UA Pub)]
    │ MQTT / AMQP

[メッセージブローカー]


[クラウド(OPC UA Sub)]

セキュリティモード

モード説明
None暗号化・署名なし(テスト用のみ)
Signメッセージ署名のみ(改ざん検知)
SignAndEncrypt署名+暗号化(本番推奨)

X.509証明書による相互認証をサポートし、エンドポイント単位でセキュリティポリシーを設定できます。

トランスポート

トランスポートエンコーディングポート
OPC UA Binary (opc.tcp://)バイナリ(コンパクト)4840
OPC UA HTTPSJSON/XML443
OPC UA WebSocketJSON4843

動作原理

セッション確立

Client                              Server
  |-- GetEndpoints ----------------->|  エンドポイント確認
  |<-- Endpoints --------------------|
  |-- CreateSecureChannel ----------->|  TLSライクなチャネル確立
  |<-- SecureChannel Created --------|
  |-- CreateSession ----------------->|  セッション作成
  |<-- Session Created ---------------|
  |-- ActivateSession(証明書)------>|  認証
  |<-- Session Activated -------------|
  |  [Browse/Read/Write/Subscribe等]
  |-- CloseSession ------------------>|

サブスクリプション(データ変化通知)

OPC UAのサブスクリプションは「監視項目(MonitoredItem)」を束ねた「サブスクリプション」として管理します。

Client                              Server
  |-- CreateSubscription ------------>|  (publishingInterval=500ms)
  |<-- Subscription ID=1 -----------|
  |-- CreateMonitoredItems(temp)--->|  (samplingInterval=100ms)
  |<-- MonitoredItem ID=10 ----------|
  |-- CreateMonitoredItems(press)-->|
  |<-- MonitoredItem ID=11 ----------|
  |                                  |
  | 500ms後...                       |
  |<-- Publish(temp=25.3, press=101)|  まとめて通知
  |-- PublishAck ------------------- >|

open62541での実装例

#include <open62541/server.h>
#include <open62541/server_config_default.h>

int main(void) {
    UA_Server *server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));

    /* 温度センサーノードを追加 */
    UA_VariableAttributes attr = UA_VariableAttributes_default;
    UA_Double temperature = 25.3;
    UA_Variant_setScalar(&attr.value, &temperature, &UA_TYPES[UA_TYPES_DOUBLE]);
    attr.displayName = UA_LOCALIZEDTEXT("ja", "温度");
    attr.dataType = UA_TYPES[UA_TYPES_DOUBLE].typeId;
    attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;

    UA_NodeId tempNodeId = UA_NODEID_STRING(1, "Temperature");
    UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
    UA_NodeId variableTypeNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
    UA_QualifiedName browseName = UA_QUALIFIEDNAME(1, "Temperature");

    UA_Server_addVariableNode(server, tempNodeId, parentNodeId,
                              parentReferenceNodeId, browseName,
                              variableTypeNodeId, attr, NULL, NULL);

    UA_Boolean running = true;
    UA_Server_run(server, &running);
    UA_Server_delete(server);
    return 0;
}

用途・ユースケース

製造業(スマートファクトリー)

工場内の各機械(PLC、CNC、ロボット)がOPC UAサーバーとして動作し、MES(製造実行システム)やSCADAシステムがクライアントとしてデータを収集します。

[Siemens S7-1500 PLC]    [Fanuc ロボット]    [Beckhoff PC]
        │ OPC UA               │ OPC UA              │ OPC UA
        └──────────────────────┴─────────────────────┘

                    [OPC UA Aggregation Server]

                    [MES / SCADA System]

                    [クラウド(Azure/AWS)]

エネルギー管理(スマートグリッド)

発電所・変電所の機器がOPC UAで電力データを送信し、エネルギー管理システムが最適化を行います。IEC 61850との連携規格も策定されています。

PLCとRaspberry Piの統合

# Python OPC UA クライアント(opcua-asyncio)
import asyncio
from asyncua import Client

async def main():
    url = "opc.tcp://plc.factory.local:4840"
    
    async with Client(url=url) as client:
        # ノードを名前で参照
        temp_node = client.get_node("ns=2;i=1001")
        temperature = await temp_node.read_value()
        print(f"温度: {temperature} ℃")
        
        # サブスクリプションで変化を監視
        handler = MySubscriptionHandler()
        subscription = await client.create_subscription(500, handler)
        await subscription.subscribe_data_change(temp_node)
        
        await asyncio.sleep(10)  # 10秒間データ収集

class MySubscriptionHandler:
    def datachange_notification(self, node, val, data):
        print(f"値変化: {val}")

asyncio.run(main())

コンパニオン仕様(Companion Specification)

OPC UAには産業分野ごとの「コンパニオン仕様」があり、機器のデータモデルを標準化します。

分野コンパニオン仕様
ロボットOPC UA for Robotics
工作機械OPC UA for Machine Tools (umati)
薬品製造OPC UA for Pharma
エネルギーOPC UA for Energy
半導体SEMI S2, E164

実装・開発のポイント

主要実装

実装言語ライセンス特徴
open62541CMPL 2.0最軽量、組み込み対応
opcua-asyncioPythonLGPLPythonクライアント/サーバー
node-opcuaJavaScriptMITNode.jsエコシステム
Unified AutomationC++/NET商用産業用途の商用実装
prosys OPC UAJava商用/評価版Java環境

組み込み機器での注意点

OPC UAはフル実装だとかなりのリソースを消費します。

機能最小RAM要件(目安)
OPC UA Binary(最小構成)約64KB
セキュリティ(X.509)約256KB以上
フル機能1MB以上

Cortex-M4以上のマイコンであれば最小構成で動作可能です。open62541は「amalgamated」ビルドで単一C/Hファイルに圧縮でき、組み込みへの組み込みが容易です。

# open62541のamalgamatedビルド
cmake .. -DUA_ENABLE_AMALGAMATION=ON \
         -DUA_ENABLE_ENCRYPTION=MBEDTLS \
         -DCMAKE_BUILD_TYPE=MinSizeRel

他技術との比較

項目OPC UAModbusMQTTREST API
情報モデル◎(セマンティクス)××△(OpenAPI)
セキュリティ◎(組み込み)×△(TLS外付け)○(TLS)
リアルタイム性
組み込み適合△(リソース大)
産業標準◎(IEC 62541)
クラウド統合○(Pub/Sub拡張)×

Modbusはシンプルで超軽量ですが情報モデルがなく、大規模システムの統合には限界があります。OPC UAはその対極にあり、複雑なシステムにおける意味論的な相互運用性を実現します。MQTTとの組み合わせでは、OPC UA Pub/Subを使ってMQTTトピックにOPC UAデータモデルを乗せることで、両者の長所を活かした統合が実現できます。

関連用語

参考リンク