今、話題の人工知能(AI)などで人気のPython。初心者に優しいとか言われていますが、全然優しくない! という事を、つらつら、愚痴っていきます

301.ラズパイ無双[27 OPC-UA FreeOpcUa 2]

»

初回:2023/3/1

 Raspberry Pi (ラズベリーパイ、通称"ラズパイ")で何か作ってみようという新シリーズです。これから数回に分けて、ラズパイ上にOPC-UAサーバーと、クライアントを入れて、通信させるところまで行ってみたいと思います。今回は、前回入れたサーバーを少し改造して、データ通信させてみたいと思います。

P子「前回からだいぶ空いたので、忘れちゃったわ」※1

 この企画は、ぼちぼち進めないと、こちらも用意が大変なんです。

【目次】

1.参考資料

 今回のOPC UAサーバーの改造の元ネタとなる記事です。

 ≪参考1≫
  https://misoji-engineer.com/archives/opc-ua-model.html#toc6
  OPC UAの情報モデルをサーバー作って確認してみた
  OPC UA serverのPythonのテストプログラム

 参考資料の説明は、この後で説明する改造プログラムとほとんど同じなので、ここでは省略しますが、サーバーからデータを送信することでクライアント側で受けることができるようになります。参考では、クライアントに『UaExpert』を使用していますが、次回に説明するPythonプログラムのクライアントで受信できるようにします。

2.opcua_server.py

 この、改造プログラムでは、カウンタ、クロック、CPU温度をデータ送信します。そして、クライアントからのデータを受け取る変数も定義しておきます。次回のクライアントプログラムでこれらのデータの取得方法を、色々と試したいと思います。

opcua_server.py

import time from opcua import Server from subprocess import getoutput # データ作成用に、CPU温度、クロック等を収集します。 ENDPOINT = 'opc.tcp://0.0.0.0:4840/freeopcua/server/' NAMESPACE = 'http://examples.freeopcua.github.io' def main() : # setup our server server = Server() server.set_endpoint(ENDPOINT) # setup our own namespace, not really necessary but should as spec idx = server.register_namespace(NAMESPACE) # 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" , 0) myvar.set_writable() # Set MyVariable to be writable by clients mycount = myobj.add_variable(idx, "MyCount" , 0) myclock = myobj.add_variable(idx, "MyClock" , "") mythermal = myobj.add_variable(idx, "MyThermal" , "") # starting! server.start() try: count = 0 while True: count += 1 mycount.set_value(count) # CPUクロックを取得する clock = getoutput('vcgencmd measure_clock arm') # frequency(48)=1500345728 myclock.set_value(clock) # CPU温度を取得する therm = getoutput('vcgencmd measure_temp') # temp=62.3'C mythermal.set_value(therm) # クライアント側で書き込まれた値を取り出す。 value = myvar.get_value() # '\r' で行頭にカーソル移動。\033[K が、カーソル行の削除 # \033[2K の数字は、0:カーソル位置から行末 1:行頭からカーソル位置まで 2:カーソルのある行を消去 # 上書きだけだと、文字数が少なくなった際に、前の文字が残ったまま表示される。 # print(f'\r{count} {clock} {therm} {value}',end='') print(f'\033[2K\r{count} {clock} {therm} {value}',end='') time.sleep(1) finally: #close connection, remove subcsriptions, etc server.stop() if __name__ == '__main__': main()

3.解説

 前回の server-minimal.py の ソースコードから、もう少し変化があるデータを取れるようにしました。45

P子「というか、それが参考資料1 なのよね」

 myvar = myobj.add_variable(idx, "MyVariable" , 0) で、オブジェクトを作成したあと、myvar.set_writable() でクライアントからの書き込みができるようにしています。

 mycount = myobj.add_variable(idx, "MyCount" , 0)
 myclock = myobj.add_variable(idx, "MyClock" , "")
 mythermal = myobj.add_variable(idx, "MyThermal" , "")

 で、カウント、クロック周波数、CPU温度のデータを送信できる変数を作成しています。後は、無限ループで値を書き込んでいるだけです。少しだけ違うのは、サーバー側で画面に値を出していることです。デバッグ用です。

 コメントに書いているように、print文に、f文字列(f-strings)で変数を直接割り当てています。さらに、'\r' で行頭にカーソル移動。\033[K が、カーソル行の削除になります。end='' で改行させないので、同じ位置に書き込み続けます。改行だけだと、元の文字数が少なくなった場合、元の文字が残るので特殊記号で、カーソル行を削除しています。

4.まとめ

 今回は、サーバーを少し改造してデータ通信できる状態にしました。次回は、これをクライアントで色々な方法で受けてみようと思います。

 今後も、少し回数が増えるかもしれませんが、気長にお付き合いください。

ほな、さいなら

======= <<注釈>>=======

※1 P子「前回からだいぶ空いたので、忘れちゃったわ」
 P子とは、私があこがれているツンデレPythonの仮想女性の心の声です。

Comment(0)

コメント

コメントを投稿する