#概要
本記事ではOPC UAサーバー側のMyObject > MyVariableに対して、値を書き込み、読み出す例を示しながら、
OPC UAサーバーに対してデータを書き込み、読み出しするために最低限必要なOPC UAパケットのパラメータを示す。
Python用OPC UA Serverライブラリを使用したサーバーに対してUaExpertで接続、読み書きを行った時の通信パケットを取得する。
そのパケットを一部変更したものをサーバーに送信して、正常に通信させた。その際の備忘録を以下に示す。
※注意:OPC UAの仕様を確認したわけではなく、個人的に解析しているため、本記事の内容がすべてのOPC UAサーバーに適用できるとは限りません。
説明の流れは下記
-
サーバー側準備
-
セッション確立(クライアント側)
-
書き込み(クライアント側)
-
読み出し(クライアント側)
#環境
OPC UA Server : https://github.com/FreeOpcUa/python-opcua
Python3 : Python 3.6.9
OPC UAサーバー側IPアドレス : 192.168.1.35
OPC UAクライアント側IPアドレス : 192.168.1.104
#サーバー側準備
サーバープログラム
以下の通りサーバープログラムを実行する。
sango@example:~/opcua$ python3 serv.py
Endpoints other than open requested but private key and certificate are not set.
Listening on 0.0.0.0:4840
以下ソースコード。
import sys
sys.path.insert(0, "..")
import time
from opcua import ua, Server
if __name__ == "__main__":
# setup our server
server = Server()
server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/")
# setup our own namespace, not really necessary but should as spec
uri = "http://examples.freeopcua.github.io"
idx = server.register_namespace(uri)
# get Objects node, this is where we should put our nodes
objects = server.get_objects_node()
# populating our address space
myobj = objects.add_object(idx, "MyObject")
myvar = myobj.add_variable(idx, "MyVariable", 3535)
myvar.set_writable() # Set MyVariable to be writable by clients
# start
server.start()
try:
while True:
time.sleep(1)
finally:
#close connection, remove subcsriptions, etc
server.stop()
(参考)本例のUaExpertでのサーバーの見え方
セッション確立(クライアント側)
Hello message & Ack
Open Secure Channel Request & Response
-
Request
要求時にはSequenceNumberを設定し、以降要求の度に1ずつインクリメントする必要がある。
また、以降SequenceNumberはSecurity Sequence Numberと名称が変わる。
この例では、SequenceNumber(Security Sequence Number) : 51としている。 -
Response
SecureChannel IdとSecure Token Idをメモしておく。
この例では、SecureChannel Id: 7, Secure Token Id: 14となっている。
以降、クライアント側から要求を送信する場合、これら2つののIdをヘッダ部に設定する必要がある。
Create Session Request & Response
-
Request
この例では、先ほどメモしたSecureChannel Id: 7, Secure Token Id: 14を設定し要求を送信している。
この例では、Security Sequence Number : 52としている。
Activate Session Request & Response
-
Request
この例では、先ほどメモしたSecureChannel Id: 7, Secure Token Id: 14を設定し要求を送信している。
この例では、Security Sequence Number : 53としている。
書き込み(クライアント側)
- Request
上述の通りのOPC UAサーバー起動時にはMyObject > MyVariableに3535を格納している。
この例では、MyObject > MyVariableに対して4047(0x0fcf)を書き込んでいる。
書き込みたいNamespace Index, Identifier Numericを指定する
この例では、MyObject > MyVariableを指す、Namespace Index : 2, Identifier Numeric : 2を指定している。
(未確認)EncodingMaskにhas value(0x01)を指定する必要があるかもしれない。
Message Sizeを正しく設定しないと、サーバー側でOPC UAパケットを正しく認識できない。
Message Sizeの範囲はWireShark上のOpcUa Binary Protocolを指す。
読み出し(クライアント側)
-
Request
読み出したいNamespace Index, Identifier Numericを指定する
この例では、MyObject > MyVariableを指す、Namespace Index : 2, Identifier Numeric : 2を指定している。
読み出したいAttributeIdを指定する
この例では、Value(0x0000000d)を指定している。 -
Response
この例では、先ほど設定したMyObject > MyVariableから4047(0x0fcf)が読み出せている。
#まとめ
- クライアント側要求時にはSequenceNumberを設定し、以降要求の度に1ずつインクリメントする必要がある。
- セッション確立時に、サーバー側から指定されたSecureChannel Id, Secure Token Idを、クライアント側要求時にヘッダ部に設定する必要がある。
- クライアント側の書き込み要求時に、書き込みたいNamespace Index, Identifier Numericを指定する必要がある。
- クライアント側の読み出し要求時に、読み出したいNamespace Index, Identifier NumericとAttributeIdを指定する必要がある。