
こんにちは!「にっしんSUN」です。
前回までのブログは読んでいただけましたか?
まだ読んでいないよーという方はこちらから読んでみてください。
第5回はWi-SUN FANで実際のデータを送ってみましょう☆

鞍馬せんせい。今回は何をするのですか?

前回までは、ネットワーク構築のお話をしていました。
今回からは、実際のデータ送信についてお話します。
ネットワーク構成
今回はわかりやすくするため1対1での通信で行います。
ネットワークの構築については前回までの記事で紹介していますのでそちらをご覧ください。

init 2(ROUTER)
inf 2b,62,0,1 { FMng: changed fan join state (0 -> 1) }
inf 40,2b,8a8,12 { NBRS: added new neighbor <001d129f35c501d8>}
inf 2b,62,1,2 { FMng: changed fan join state (1 -> 2) }
inf 2b,62,2,3 { FMng: changed fan join state (2 -> 3) }
inf 2b,62,3,4 { FMng: changed fan join state (3 -> 4) }
inf 4c,3c,7318,1d00 { RPL: preferred parent <001d129f35c501d8> }
inf 40,2d,72dc,8a8 { NBRS: added address <2001:db8::1> to <001d129f35c501d8>}
inf 60,4c,70f8,0 { DHCPv6: binding address <2001:db8::fb/128> }
inf 4c,37,0,0 { RPL: connected to DODAG }
inf 2b,62,4,5 { FMng: changed fan join state (4 -> 5) }
>
子機側でこのようにjoin state 5になればデータ送受信が可能な状態です。
送信プロトコル
Wi-SUN FANでは2種類の通信プロトコルが使用可能です。
・UDP
・TCP/IP
順に見ていきましょう。
UDP
UDPでバイナリコードを送信するためには次のように入力します。
>udps <宛先IPアドレス> <送信データ>
このコマンドでは、ASCII-HEX文字列を<送信データ>に入れることができます。
では、実際に送信してみましょう。
中継機から親機にデータ送信するときは・・・
>udps 2001:db8::1 48656c6c6f
親機側のlogを見てみると・・・
udpr <2001:db8::dd> 48656c6c6f
と表示されています。
何やら送信した文字列が届いていますが、詳しく見てみると
>udpr <送信元IPアドレス> <受信データ>
なので、2001:db8::ddから<48656c6c6f>というデータが届いていることがわかりますね。

ASCII-HEX文字
文字コードの標準規格として広く普及している「ASCII」(American Standard Code for Information Interchange)を16進数で表した文字。
今回送信した" 48656c6c6f"は"Hello"という意味。

何のデータが送られてきたか
一目ではわかりませんね。

テキストデータで送信も可能ですよ!
UDPでテキストデータを送信するためには次のように入力します。
>udpst <宛先IPアドレス> <"送信データ">
このコマンドでは、テキストを<"送信データ">に入れることができます。
では、実際に送信してみましょう。
先程と同じく、中継機から親機にデータ送信するときは・・・
>udpst 2001:db8::1 "Hello"
親機側のlogを見てみると・・・
udprt <2001:db8::dd> "Hello"
と表示されています。
送信時には"udpst"と入力,受信時には"udprt"と表示されます。

では、この"udpst"を使って私とにっしんさんで会話をしてみましょう。
>
udprt <2001:db8::dd> "こんにちはにっしんさん"
>udpst 2001:db8::dd "こんにちは、鞍馬せんせい"
udprt <2001:db8::dd> "UDPの使い方はわかりましたか?"
>udpst 2001:db8::dd "はい!完璧です!"
udprt <2001:db8::dd> "OK、次はTCPにいってみよう"
>
TCP/IP
TCP/IPでバイナリコードを送信するためには次のように入力します。
>tcps <宛先IPアドレス> <送信データ>
UDPで紹介した"udps"コマンドと同じで、このコマンドでは、ASCII-HEX文字列を<送信データ>に入れることができます。
では、実際に送信してみましょう。
中継機から親機にデータ送信するときは・・・
>tcps 2001:db8::1 48656c6c6f
親機側のlogを見てみると・・・
tcpr <2001:db8::dd> 48656c6c6f
とデータが届いていることがわかりますね。
表示される内容は"udps","udpr"と同じですので、省略します。

データ送信コマンドを理解したら、
なにか作れそうな気がしてきました☆

そうですね。
では次に簡単なWi-SUN FANを使ったプログラムを作成してみましょう。
サンプルプログラム
今回は、Wi-SUN FANとつながっているPCのCPUとメモリの使用率を取得して、Wi-SUN FANで送信し、受信側でデータの確認をしてみましょう。

環境
PC:Windows 10
Python 3.8.3
準備
以下のモジュールをpipからインストールします。
C:¥>pip install pyserial
C:¥>pip install psutil
プログラム
まずは送信側(中継機側)から
import psutil import json import serial import time PC_data = {"Memory_usage":0,"CPU_usage":0} send_data = {"udpst" : {"ADDR":"2001:db8::1","data":""}} #シリアルOpen ボーレート115200 ser = serial.Serial('COM7',115200,timeout=None) while True: # メモリとCPUの利用情報を取得 memory = psutil.virtual_memory() cpu_percent = psutil.cpu_percent(interval=1) #使用率をデータに格納 PC_data['Memory_usage'] = memory.percent PC_data['CPU_usage'] = cpu_percent #送信データの"data"部に使用率データを格納 send_data['udpst']['data'] = json.dumps(PC_data) #辞書型を文字列に変換 sr = json.dumps(send_data) #{"udpst": {"ADDR": "2001:db8::1", "data": "{"Memory_usage": 84.8, "CPU_usage": 7.2}"}} ser.write(bytes(sr + '\r\n' ,encoding = "utf-8")) time.sleep(5)
9行目
ser = serial.Serial('COM7',115200,timeout=None)
で、送信側のWi-SUN FAN端末と接続して
21~23行目
sr = json.dumps(send_data)
#{"udpst": {"ADDR": "2001:db8::1", "data": "{"Memory_usage": 84.8, "CPU_usage": 7.2}"}}
ser.write(bytes(sr + '\r\n' ,encoding = "utf-8"))
で送信コマンドを作成して送信しています。

あれ?さっきまでとUDPで
データ送信するコマンドが違いますね?

コマンド自体は同じです。
ただし、プログラムで扱いやすいJSONフォーマットで記載しています。
JSONフォーマット
通常のコマンドでは、このような記載になっていました。
>udpst 2001:db8::1 "Hello"
udprt <2001:db8::dd> "Hello"
JSONフォーマットでは次のようになります。
>{"udpst": {"ADDR": "2001:db8::1", "data": "Hello"}}
{ "udpr" : { "ADDR" : "2001:db8::dd", "data" : " Hello " } }
JSONフォーマットにすることで、プログラムが扱いやすくなるのでとても便利です。
最後に受信側です。
import threading
import serial
import time
import json
#シリアルOpen ボーレート115200
ser = serial.Serial('COM5',115200,timeout=None)
while True:
if(ser.inWaiting() > 0):
rcv_data = ser.readline().decode('ascii')
#{"udprt": {"ADDR": "2001:db8::dd", "data": "{"Memory_usage": 84.8, "CPU_usage": 7.2}"}}
d = json.loads(rcv_data)
r_data = json.loads(d['udprt']['data'])
print('メモリ使用率:' , r_data['Memory_usage']) #メモリ使用率:84.8
print('CPU使用率:' , r_data['CPU_usage']) #CPU使用率 7.2
time.sleep(0.01)
送信側のプログラムと同じように
7行目
ser = serial.Serial('COM5',115200,timeout=None)
で、受信側のWi-SUN FAN端末と接続して
11行目
rcv_data = ser.readline().decode('ascii')
で受信しています。
結果
C:¥Users¥kurama>python rcv.py
メモリ使用率:84.8
CPU使用率:7.2
メモリ使用率:85.0
CPU使用率:7.3
メモリ使用率:82.8
CPU使用率:7.5
メモリ使用率:84.6
CPU使用率:7.7
^C
C:¥Users¥kurama>

簡単にWi-SUN FANを使ったプログラムができました☆

センサの値を集めるネットワークなどは
シンプルなプログラムでできますね。

今回のまとめ
☆ Wi-SUN FANではUDPとTCP/IPの2つのプロトコルが使える
☆ プログラムで使うときはJSONフォーマットが便利!
☆ 簡単なプログラムでセンサネットワークができる!