PythonでOPC UAを実装する方法|基本から応用まで徹底解説

プログラミング
記事内に広告が含まれています。
スポンサーリンク

OPC UAとは?

brian
brian

PythonでOPC UAを実装してみませんか?このガイドでは、基本からサーバー・クライアントの作成方法まで初心者向けに解説しています。産業IoTやデータ通信に興味がある方は、ぜひチェックしてみてください!

OPC UAの概要と用途

OPC UA(Open Platform Communications Unified Architecture)は、産業オートメーション分野で広く利用されている通信プロトコルの一つです。工場の機械やセンサー、SCADAシステム(監視制御とデータ収集)など、さまざまな機器やシステム間でデータをやり取りするための標準的な仕組みとして開発されました。

従来のOPC(OPC DA、OPC HDA、OPC AE)は、Windows環境に依存していたため、異なるOSやクラウド環境との連携が難しいという課題がありました。しかし、OPC UAはプラットフォーム非依存であり、Linuxやクラウド環境でも動作するため、IoT(モノのインターネット)時代に適した通信技術として注目されています。

OPC UAと従来のOPCの違い

OPC UAは、従来のOPCと比べて以下のような違いがあります。

プラットフォーム非依存

従来のOPCはWindows環境に依存していましたが、OPC UAは異なるOSやクラウド環境でも動作します。PythonやJava、C++など、さまざまな言語での実装が可能です。

統一されたデータモデル

従来のOPCはデータアクセス(DA)、ヒストリカルデータ(HDA)、アラーム&イベント(AE)などの異なる仕様に分かれていました。しかし、OPC UAはすべてのデータ種類を統一したモデルで扱うことができます。

高いセキュリティ

OPC UAでは、通信の暗号化、認証、アクセス制御が標準でサポートされています。これにより、データの改ざんや盗聴のリスクを抑えながら、安全にデータをやり取りできます。

OPC UAのメリット

OPC UAを活用することで、以下のようなメリットがあります。

  • 異なるシステム間でのスムーズなデータ交換
    • 例えば、工場のPLC(プログラマブルロジックコントローラー)とクラウドのデータベースを直接接続し、リアルタイムでデータを分析できるようになります。
  • 拡張性が高い
    • データモデルを自由に定義できるため、新しい機器やシステムにも対応しやすくなっています。
  • 将来の産業技術との親和性が高い
    • 産業用IoT(IIoT)やAI、ビッグデータ分析などの最新技術と組み合わせやすく、工場のスマート化に貢献します。
スポンサーリンク

PythonでのOPC UA開発環境

必要なライブラリ

PythonでOPC UAを扱うには、opcuaというライブラリを使用します。これは、OPC UAサーバーやクライアントをPythonで実装するためのオープンソースライブラリです。公式のOPC Foundationが提供するものではありませんが、広く利用されており、基本的な機能を備えています。

opcuaライブラリを使用すると、次のようなことが可能になります。

  • OPC UAサーバーの構築
  • ノード(データポイント)の作成と管理
  • クライアントからのデータ読み取り・書き込み
  • サブスクリプションを利用したデータのリアルタイム監視

opcuaライブラリのインストール

まず、Pythonの仮想環境を作成し、必要なライブラリをインストールすることをおすすめします。

仮想環境の作成(推奨)

Bash
python -m venv opcua_env
source opcua_env/bin/activate  # macOS/Linux
opcua_env\Scripts\activate     # Windows

仮想環境については以下の記事の「Pythonで仮想環境を作成しよう」も参考にしてください。

opcuaライブラリのインストール

仮想環境を作成したら、pipを使ってopcuaライブラリをインストールします。

Bash
pip install opcua

インストールが完了したら、正しく動作するか確認してみましょう。

インストール確認

Pythonのインタラクティブシェルを開き、次のコードを実行してください。

Python
from opcua import Server, Client
print("OPC UAライブラリが正しくインストールされています。")

エラーメッセージが出なければ、インストールは成功です。

基本的なセットアップ

OPC UAを使用するには、サーバークライアントの両方を実装する必要があります。

以下、それぞれの基本コードと詳細な説明を紹介します。

OPC UAサーバーのサンプルコード

Python
from opcua import Server
import datetime
import random

# サーバーのインスタンスを作成
server = Server()

# エンドポイント(クライアントが接続するアドレス)を設定
server.set_endpoint("opc.tcp://localhost:4840/freeopcua/server/")

# サーバーの名前空間を作成
uri = "http://example.org/opcua"
idx = server.register_namespace(uri)

# オブジェクトノードを作成
objects = server.get_objects_node()
device = objects.add_object(idx, "Device")

# 変数ノード(データポイント)を作成
temperature = device.add_variable(idx, "Temperature", 25.0)
temperature.set_writable()  # クライアントが値を変更できるようにする

# サーバーを起動
server.start()
print("OPC UA サーバーが起動しました。")

try:
    while True:
        # 温度データをランダムに更新
        temp_value = round(20 + random.uniform(-5, 5), 2)
        temperature.set_value(temp_value)
except KeyboardInterrupt:
    print("サーバーを停止します。")
    server.stop()
コードの解説
  1. Server() を使用してOPC UAサーバーのインスタンスを作成します。
  2. set_endpoint("opc.tcp://localhost:4840/freeopcua/server/")
    • クライアントが接続するためのエンドポイントURLを設定します。
    • localhost はローカル環境を指しますが、実際の運用ではIPアドレスを設定します。
  3. register_namespace(uri)
    • uri を使用して、サーバー独自の名前空間を登録します。
    • 名前空間は、データの整理やクライアントとの識別に使用されます。
  4. get_objects_node() を使い、データを格納するオブジェクトを作成します。
  5. add_variable(idx, "Temperature", 25.0) を使い、Temperature という変数ノードを作成します。
  6. set_writable() を設定することで、クライアント側からデータを書き換え可能にします。
  7. server.start() でサーバーを起動し、while True: のループ内でデータを更新します。
  8. KeyboardInterrupt (Ctrl+C) でサーバーを正常に停止します。

このコードを実行すると、ローカル環境でOPC UAサーバーが動作し、Temperature という変数の値が徐々に増加していく仕組みになっています。

OPC UAクライアントのサンプルコード

別のターミナルを開き、次のコードを実行することで、サーバーに接続してデータを取得できます。

Python
from opcua import Client

# クライアントのインスタンスを作成
client = Client("opc.tcp://localhost:4840/freeopcua/server/")

try:
    client.connect()
    print("サーバーに接続しました。")

    # Temperatureノードの値を取得
    node = client.get_node("ns=2;i=2")  # ns=2 は作成した名前空間、i=2 は変数のノードID
    while True:
        value = node.get_value()
        print(f"現在の温度: {value}°C")
except KeyboardInterrupt:
    print("クライアントを終了します。")
finally:
    client.disconnect()
コードの解説
  1. Client("opc.tcp://localhost:4840/freeopcua/server/")
    • クライアントのインスタンスを作成し、指定したエンドポイントに接続します。
  2. client.connect()
    • OPC UAサーバーに接続します。
  3. get_node("ns=2;i=2")
    • Temperatureノードを取得します。
    • ns=2 は名前空間ID、i=2 はノードIDを指します。
  4. get_value()
    • 取得したノードの現在の値を取得し、温度を表示します。
  5. while True:
    • 温度データをリアルタイムで取得し続けるためのループです。
  6. KeyboardInterrupt (Ctrl+C) でクライアントを終了します。

実行結果

  1. サーバー側のターミナル
Bash
OPC UA サーバーが起動しました。Ctrl+Cで停止できます。
  1. クライアント側のターミナル
Bash
サーバーに接続しました。
現在の温度: 25.0°C
現在の温度: 25.1°C
現在の温度: 25.2°C
...

これで、基本的な開発環境が整い、PythonでOPC UAサーバーとクライアントが動作することが確認できました。

スポンサーリンク

PythonでOPC UAサーバーを作成する

OPC UAサーバーとは?

OPC UAサーバーは、センサーや機械のデータを収集し、クライアントに提供する役割を持ちます。Pythonを使えば、簡単にOPC UAサーバーを作成し、外部システムとデータをやり取りできます。

サーバーの主な処理の流れは以下の通りです。

  1. サーバーのインスタンスを作成
  2. エンドポイント(接続先のURL)を設定
  3. 名前空間(Namespace)を登録
  4. オブジェクトノード(データを格納するコンテナ)を作成
  5. 変数ノード(データポイント)を作成
  6. サーバーを起動
  7. クライアントからのアクセスを待機

OPC UAサーバーの基本コード

以下のPythonコードは、OPC UAサーバーを作成し、Temperature という変数ノードを管理するシンプルな例です。

Python
from opcua import Server
import datetime

# サーバーのインスタンスを作成
server = Server()

# エンドポイント(クライアントが接続するアドレス)を設定
server.set_endpoint("opc.tcp://localhost:4840/freeopcua/server/")

# サーバーの名前空間を作成
uri = "http://example.org/opcua"
idx = server.register_namespace(uri)

# オブジェクトノードを作成
objects = server.get_objects_node()
device = objects.add_object(idx, "Device")

# 変数ノード(データポイント)を作成
temperature = device.add_variable(idx, "Temperature", 25.0)
temperature.set_writable()  # クライアントが値を変更できるようにする

# サーバーを起動
server.start()
print("OPC UA サーバーが起動しました。Ctrl+Cで停止できます。")

try:
    while True:
        pass  # 無限ループでサーバーを維持
except KeyboardInterrupt:
    print("サーバーを停止します。")
    server.stop()
コードの解説
  1. サーバーの作成とエンドポイントの設定
    • Server() を使ってサーバーのインスタンスを作成します。
    • set_endpoint() でクライアントが接続するためのURLを設定します。
    • opc.tcp://localhost:4840/freeopcua/server/ は、ローカルホストのポート4840でサーバーを待ち受ける設定です。
  2. 名前空間(Namespace)の登録
    • register_namespace(uri) を使用し、サーバー独自の名前空間を登録します。
    • http://example.org/opcua のようなURLを設定し、idx(名前空間ID)を取得します。
    • このidxは、サーバー内でデータを整理し、一意に識別するために使われます。
  3. オブジェクトノードの作成
    • get_objects_node() を使って、サーバーのオブジェクトノード(データを格納するルートオブジェクト)を取得します。
    • add_object(idx, "Device") を使って、Device というオブジェクトノードを作成します。
    • Device は、温度センサーや機械などのデータをまとめるコンテナとして使用できます。
  4. 変数ノード(データポイント)の作成
    • add_variable(idx, "Temperature", 25.0) で、Temperature という変数ノードを作成し、初期値を 25.0 に設定します。
    • set_writable() を適用することで、クライアントが値を変更できるようになります。
    • 例えば、クライアントから新しい温度値を設定することが可能になります。
  5. サーバーの起動と待機
    • server.start() を実行すると、サーバーがバックグラウンドで動作を開始します。
    • print() で起動メッセージを表示し、クライアントが接続できる状態にします。
    • while True: を使用して無限ループを作り、サーバーを継続稼働させます。
  6. サーバーの停止処理
    • KeyboardInterrupt (Ctrl+C を押したとき) を検知し、サーバーを停止する処理を実装します。
    • server.stop() を実行して、適切にサーバーを終了させます。
    • これにより、サーバーが安全にシャットダウンされ、リソースが適切に解放されます。

サーバーの動作確認

サーバーの起動

このサーバーコードを実行すると、以下のようなメッセージが表示されます。

Bash
OPC UA サーバーが起動しました。Ctrl+Cで停止できます。

この状態で、クライアントが接続できるようになります。

スポンサーリンク

PythonでOPC UAクライアントを作成する

クライアントの基本構造

OPC UAクライアントは、サーバーに接続し、データを取得したり、書き込んだりする役割を持ちます。Pythonのopcuaライブラリを使えば、簡単にクライアントを実装できます。

クライアントの基本的な流れは以下の通りです。

  1. クライアントのインスタンスを作成
  2. サーバーに接続
  3. ノード(データポイント)を取得
  4. データの読み取り・書き込み
  5. サーバーとの接続を解除

クライアントの基本コード

まずは、シンプルなクライアントを作成し、OPC UAサーバーに接続してデータを取得するコードを見てみましょう。

Python
from opcua import Client

# クライアントのインスタンスを作成
client = Client("opc.tcp://localhost:4840/freeopcua/server/")

try:
    # サーバーに接続
    client.connect()
    print("サーバーに接続しました。")

    # 温度データを管理するノードを取得
    node = client.get_node("ns=2;i=2")  # ns=2(名前空間ID)、i=2(ノードID)
    
    # 現在の温度を取得
    value = node.get_value()
    print(f"現在の温度: {value}°C")

except Exception as e:
    print(f"エラーが発生しました: {e}")
finally:
    # サーバーとの接続を解除
    client.disconnect()
    print("クライアントを終了しました。")
コードの解説
  1. Client("opc.tcp://localhost:4840/freeopcua/server/")
    • OPC UAサーバーに接続するためのクライアントを作成します。
    • "opc.tcp://localhost:4840/freeopcua/server/" はサーバーのエンドポイントです。
  2. client.connect()
    • サーバーとの接続を確立します。
  3. get_node("ns=2;i=2")
    • サーバー内のTemperature ノードを取得します。
    • ns=2 は名前空間ID、i=2 はノードIDを指します。
  4. get_value()
    • 取得したノードの現在の値(温度)を読み取ります。
  5. client.disconnect()
    • 使用後は必ず接続を解除し、リソースを解放します。

このコードを実行すると、OPC UAサーバーに接続し、Temperature ノードの値を取得することができます。

データの書き込み

OPC UAでは、クライアント側からサーバーのデータを更新することも可能です。次のコードでは、Temperature の値を変更してみます。

Python
from opcua import Client

# クライアントのインスタンスを作成
client = Client("opc.tcp://localhost:4840/freeopcua/server/")

try:
    client.connect()
    print("サーバーに接続しました。")

    node = client.get_node("ns=2;i=2")  
    print(f"現在の温度: {node.get_value()}°C")

    # 新しい温度を設定
    node.set_value(30.5)
    print(f"新しい温度を設定: {node.get_value()}°C")

except Exception as e:
    print(f"エラーが発生しました: {e}")
finally:
    client.disconnect()
    print("クライアントを終了しました。")
コードの解説
  1. node.set_value(30.5)
    • Temperature ノードの値を 30.5 に変更します。
    • set_value() を使用すると、変数の値を更新できます。
    • ただし、サーバー側で set_writable() を設定していないと変更できません。
  2. print(f"新しい温度を設定: {node.get_value()}°C")
    • 値を変更後、再度 get_value() を使って、新しい値が適用されたか確認します。

実行すると、サーバー側のTemperatureノードの値が30.5に変更されます。

データの監視(Subscription)

OPC UAには、データの変更をリアルタイムで監視する「サブスクリプション(Subscription)」という仕組みがあります。クライアントが特定のノードを監視し、値が変わるたびに通知を受け取ることができます。

次のコードでは、Temperatureノードの値を監視し、変更があるたびに表示します。

Python
from opcua import Client, ua
import time

# 変更通知のためのハンドラー
class SubHandler:
    def datachange_notification(self, node, val, data):
        print(f"データが更新されました: {val}°C")

# クライアントの作成
client = Client("opc.tcp://localhost:4840/freeopcua/server/")

try:
    client.connect()
    print("サーバーに接続しました。")

    # 温度データのノードを取得
    node = client.get_node("ns=2;i=2")  

    # サブスクリプションを作成(1秒ごとに監視)
    handler = SubHandler()
    sub = client.create_subscription(1000, handler)
    handle = sub.subscribe_data_change(node)

    while True:
        time.sleep(1)  # 継続的に監視
except KeyboardInterrupt:
    print("監視を終了します。")
finally:
    client.disconnect()
コードの解説
  1. class SubHandler
    • サーバーからのデータ更新通知を受け取るためのクラスを作成します。
    • datachange_notification(self, node, val, data) が呼び出されると、新しい値 val を取得できます。
  2. client.create_subscription(1000, handler)
    • 1000ms(1秒)ごとにデータの変更を監視するサブスクリプションを作成します。
  3. sub.subscribe_data_change(node)
    • 指定したノード(Temperature)の値が変化すると、SubHandler クラスの datachange_notificationメソッドが実行されます。
  4. while True: time.sleep(1)
    • プログラムを継続的に実行し、サブスクリプションが動作し続けるようにします。

このスクリプトを実行すると、サーバーのTemperatureノードの値が変化するたびに、新しい値が表示されます。

スポンサーリンク

応用:Pythonを使ったOPC UAアプリケーション

OPC UAは、産業オートメーションやIoTの分野で広く活用されています。ここでは、Pythonを使ったOPC UAの具体的な応用例をいくつか紹介します。

産業用IoT(IIoT)での活用

工場内のセンサー監視システム

工場内の温度・湿度・圧力などのセンサーからリアルタイムでデータを収集し、監視システムに送信することができます。PythonでOPC UAサーバーを構築し、センサーデータを管理することで、異常検知や設備の予知保全が可能になります。

実装例:温度センサー監視システム

Python
from opcua import Server
import random
import time

server = Server()
server.set_endpoint("opc.tcp://localhost:4840/freeopcua/server/")

uri = "http://example.org/opcua"
idx = server.register_namespace(uri)

objects = server.get_objects_node()
sensor = objects.add_object(idx, "TemperatureSensor")
temperature = sensor.add_variable(idx, "Temperature", 25.0)
temperature.set_writable()

server.start()
print("温度センサー監視システムが起動しました。")

try:
    while True:
        temp_value = round(20 + random.uniform(-5, 5), 2)
        temperature.set_value(temp_value)
        print(f"現在の温度: {temp_value}°C")
        time.sleep(2)
except KeyboardInterrupt:
    print("システムを停止します。")
    server.stop()
コードの解説
  1. サーバーのセットアップ
    • Server() を使用してOPC UAサーバーを作成し、エンドポイントを設定。
    • register_namespace(uri) で名前空間を登録し、データを整理。
  2. オブジェクトと変数ノードの作成
    • add_object(idx, "TemperatureSensor") で温度センサーを表すオブジェクトを作成。
    • add_variable(idx, "Temperature", 25.0) で Temperature 変数ノードを作成し、初期値を25.0℃に設定。
    • set_writable() を使用し、クライアントが値を変更できるようにする。
  3. データのリアルタイム更新
    • random.uniform(-5, 5) を使い、温度値をランダムに変化させる。
    • set_value(temp_value) を使用し、ノードの値を更新。
    • time.sleep(2) で2秒ごとにデータを更新し、クライアントがリアルタイムで値を取得できるようにする。

このサーバーを動かすと、温度データが定期的に更新され、クライアントがリアルタイムでデータを取得できます。

SCADAシステムとの統合

**SCADA(Supervisory Control and Data Acquisition)**とは、工場の機器やセンサーを監視・制御するシステムのことです。PythonでOPC UAクライアントを作成し、SCADAシステムにデータを提供することで、現場の状況を可視化できます。

例えば、以下のようなデータフローを作成できます。

  1. **センサー(PLC)**がデータを取得
  2. OPC UAサーバーがデータを管理
  3. SCADAクライアントがデータを取得し、ダッシュボードに表示

Pythonを使えば、OPC UAクライアントとしてSCADAシステムと接続し、データの可視化や制御を行うことも可能です。

クラウドとの連携(AWS, Azure IoT Hubなど)

最近では、OPC UAのデータをクラウドに送信し、AI解析やビッグデータ処理を行うケースが増えています。Pythonを使えば、OPC UAクライアントとしてクラウドサービス(AWS IoT、Azure IoT Hub、Google Cloud IoTなど)と連携できます。

実装例:OPC UAデータをクラウドに送信(MQTTを使用)

Pythonのpaho-mqttライブラリを使って、OPC UAのデータをMQTTブローカーに送信し、クラウド上で解析することができます。

Python
from opcua import Client
import paho.mqtt.client as mqtt
import time

# OPC UAクライアントの設定
opc_client = Client("opc.tcp://localhost:4840/freeopcua/server/")
opc_client.connect()

# MQTTクライアントの設定
mqtt_client = mqtt.Client()
mqtt_client.connect("broker.hivemq.com", 1883, 60)  # パブリックMQTTブローカーを使用

try:
    while True:
        node = opc_client.get_node("ns=2;i=2")
        value = node.get_value()
        
        # MQTTでクラウドに送信
        mqtt_client.publish("factory/temperature", f"{value}")
        print(f"クラウドに送信: {value}°C")
        
        time.sleep(5)
except KeyboardInterrupt:
    print("システムを終了します。")
finally:
    opc_client.disconnect()
    mqtt_client.disconnect()
コードの解説
  1. OPC UAクライアントのセットアップ
    • Client("opc.tcp://localhost:4840/freeopcua/server/") でサーバーに接続。
    • connect() を使用してOPC UAサーバーと通信を確立。
  2. MQTTクライアントの設定
    • mqtt.Client() を使用してMQTTクライアントを作成。
    • connect("broker.hivemq.com", 1883, 60) で、HiveMQのパブリックブローカーに接続。
  3. データの取得とクラウド送信
    • get_node("ns=2;i=2") を使用し、OPC UAサーバーから温度データを取得。
    • mqtt_client.publish("factory/temperature", f"{value}") でクラウドにデータを送信。
    • time.sleep(5) で5秒ごとにデータを送信し、リアルタイムでクラウドにデータを蓄積。
  4. システムの正常な終了処理
    • KeyboardInterrupt を検知し、opc_client.disconnect() でOPC UAの接続を解除。
    • mqtt_client.disconnect() でMQTT接続を閉じ、リソースを解放。

このコードを実行すると、OPC UAのデータが定期的にクラウドに送信されます。クラウド上でデータを可視化し、異常検知や機械学習による分析を行うことができます。

スポンサーリンク

まとめ

Pythonを使ったOPC UAの応用例として、以下のようなシステムを構築できることがわかりました。

  • 産業用IoT(IIoT):リアルタイムでセンサーデータを収集・監視
  • SCADAシステムとの統合:設備の遠隔監視・制御
  • クラウドとの連携:IoTデータをクラウドに送信し、AI解析や可視化を実施

このように、OPC UAは産業オートメーションにおいて非常に強力な技術です。Pythonを活用することで、比較的簡単にシステムを構築し、データの収集・分析を行うことができます。

brian
brian

ここまで読んでいただきありがとうございます!

UdemyのPythonコースにはオンラインで学習ができる動画コンテンツがたくさんあります。

当ブログのような文章メインの説明では足りない箇所を補えると思うので、もっと詳しく勉強したいという方はぜひチェックしてみてください!

コメント

タイトルとURLをコピーしました