Raspberry Piでモノプラ - py-monopla公開
さくらのモノプラットフォーム(モノプラ)に接続するデバイス向けのPythonライブラリ「py-monopla」を公開しました。本記事ではpy-monoplaの簡単な説明と実際にRaspberry Pi 4で付属のサンプルプログラムを動作させるまでの手順をご紹介します。
py-monoplaとは?
py-monoplaはRaspberry PiなどのLinuxが動作するデバイス向けのクライアントライブラリです。MITライセンスの元に公開されたオープンソースプログラムですので商用利用など利用用途による制限はありません。「さくらのモノプラットフォーム」で提供している以下の機能のクライアントを提供します。
プラットフォーム機能
現在のところプロジェクトに登録されているセキュアモバイルコネクトSIM経由の接続でのみ使用可能です。インターネット経由の場合API呼び出しがエラーとなります。
Raspberry Pi 4で動かしてみる
ここからは実際にRaspberry Pi 4でpy-monopla付属のサンプルプログラムを動作させるまでの手順をご紹介します。
※2023年9月現在の手順となります。将来、各デバイスの入手状況やセットアップ方法の変化、OSのバージョンアップ等で再現できなくなる可能性があります。ご了承ください。
用意するもの
今回は以下のデバイスを用意しpy-monoplaのインストールとサンプルプログラムの実行を行いました。
- Raspberry Pi OSがインストールされたRaspberry Pi 4
- カードタイプのセキュアモバイルコネクトSIM
- LTEデバイス(今回はSORACOM Onyx LTE USB ドングル SC-QGLC4-C1を使用)
SORACOM Onyxは個人でも1つから購入できること、技適の心配が無いこと、モバイルルータータイプでは無くOSからモデムとして見えコントロールしやすいことから採用しました。
今回は未確認ですがセキュアモバイルコネクト経由でデバイスアダプタへの接続が可能であれば他のLTEデバイスでも動作するのではと思います。
Raspberry Pi 4インストール
Raspberry Pi 4の準備
公式サイトのGetting startedなどを参考にRaspberry Pi OSをインストールし動作するようにしてください。また、インストール中にインターネットへの接続が必要になりますので接続できるようにしておいてください。
SIMの準備
セキュアモバイルコネクトSIMを「さくらのモノプラットフォーム」から使用できるようにします。
以上を参考にSIMをプロジェクトに登録してください。
LTEドングルの準備
SORACOM Onyxのセットアップ手順を元にセキュアモバイルコネクト向けの調整をしながら進めます。
SIM
SORACOM Onyxのカバーを外しセキュアモバイルコネクトのSIMを挿します。
参考: IoT SIM の挿入 / 取り出し
Raspberry Piへ接続
SORACOM OnyxをRaspberry Pi 4のUSBポートに挿します。
Raspberry Pi OSが認識しているか確認します。
pi@monoplapi:~ $ ls /dev/ttyUSB* /dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3
/dev以下にデバイスファイルttyUSB0、ttyUSB1、ttyUSB2、ttyUSB3が見えていれば正しく認識しています。一旦、SORACOM OnyxをUSBポートから取り外します。
LTE接続設定
SORACOM Onyxのセットアップスクリプトをダウンロードします。
pi@monoplapi:~ $ curl -O https://soracom-files.s3.amazonaws.com/setup_air.sh
ダウンロードしたセットアップスクリプトsetup_air.shを実行します。
pi@monoplapi:~ $ sudo bash setup_air.sh sakura sakura sakura
APNにsakuraを指定します。セキュアモバイルコネクトではユーザー名とパスワードは任意のもので良いので双方ともsakuraを指定します。
スクリプトの実行が完了すると、/etc/udev/rulesにUSBドングルの認識に必要な設定、/etc/networks/interfacesにネットワークインターフェスの設定、/etc/wvdial.confにPPP接続の設定が追加されます。
キャリア自動選択ではなくSoftBankを選択するように/etc/wvdial.confの初期化スクリプトを編集します。(AT+COPS=1,2,"44020"を最初に追加する)
/etc/wvdial.conf
[Dialer Defaults] Init1 = AT+COPS=1,2,”44020” Init2 = AT+CFUN=1 Init3 = ATZ Init4 = AT+CGDCONT=1,”IP”,”sakura” Dial Attempts = 0 Stupid Mode = 1 Modem Type = Analog Modem Dial Command = ATD Stupid Mode = yes Baud = 460800 New PPPD = yes ISDN = 0 APN = sakura Phone = *99***1# Username = sakura Password = sakura Carrier Check = no Auto DNS = 1 Check Def Route = 1
LTE接続の確認
SORACOM OnyxをRaspberry Pi 4のUSBポートに挿します。認識するまで10秒ほど時間がかかります。あわてずに待ちましょう。ip aコマンドでppp0で認識していることを確認します。
pi@monoplapi:~ $ ip a : 省略 : 6: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1464 qdisc pfifo_fast state UNKNOWN group default qlen 3 link/ppp inet 10.xxx.xxx.xxx peer 10.xxx.xxx.xxx/32 scope global ppp0 valid_lft forever preferred_lft forever
ping connector.sipf.iot.sakura.ad.jpで疎通を確認します。
pi@monoplapi:~ $ ping connector.sipf.iot.sakura.ad.jp PING edge.gslb.prod.iot.sakura.ad.jp (xxx.xxx.xxx.xxx) 56(84) bytes of data. 64 bytes from xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): icmp_seq=1 ttl=62 time=67.5 ms 64 bytes from xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): icmp_seq=2 ttl=62 time=108 ms 64 bytes from xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): icmp_seq=3 ttl=62 time=66.9 ms 64 bytes from xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): icmp_seq=4 ttl=62 time=86.9 ms ^C — edge.gslb.prod.iot.sakura.ad.jp ping statistics — 4 packets transmitted, 4 received, 0% packet loss, time 3001ms rtt min/avg/max/mdev = 66.871/82.432/108.438/17.039 ms
SORACOM OnyxをRaspberry Pi 4のUSBポートから取り外します。
py-monoplaのインストール
GitHubからpy-monoplaのリポジトリをクローンします。
pi@monoplapi:~ $ sudo apt install git pi@monoplapi:~ $ git clone https://github.com/sakura-internet/py-monopla.git
TLS(SSL)のルート証明書をインストールします。
pi@monoplapi:~ $ cd py-monopla/ pi@monoplapi:~/py-monopla $ sudo ./install_crt.sh Updating certificates in /etc/ssl/certs… 1 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d… done. lrwxrwxrwx 1 root root 71 Sep 27 15:56 Sakura_Iot_SIPF_Root_CA_1.pem -> /usr/share/ca-certificates/SakuraInternet/Sakura_Iot_SIPF_Root_CA_1.crt
venvでPythonの環境を作ります。
pi@monoplapi:~/py-monopla $ sudo apt-get install python3-venv pi@monoplapi:~/py-monopla $ python3 -m venv venv
作成したPython環境を有効にした後、pipでpy-monoplaをインストールします。
pi@monoplapi:~/py-monopla $ source venv/bin/activate (venv) pi@monoplapi:~/py-monopla $ pip install . Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Processing /home/pi/py-monopla Installing build dependencies ... done Getting requirements to build wheel ... done Preparing wheel metadata ... done Building wheels for collected packages: py-monopla Building wheel for py-monopla (PEP 517) ... done Created wheel for py-monopla: filename=py_monopla-0.1-py3-none-any.whl size=5655 sha256=213b6d85c28bfd07913b771710db49ff6ed4fa06add7aa000a1fc77a25dd8389 Stored in directory: /home/pi/.cache/pip/wheels/74/53/ec/ba62fdf7483117fcd6665b66ecc0e1bb95086e75ad87a63896 Successfully built py-monopla Installing collected packages: py-monopla Successfully installed py-monopla-0.1
以上で、py-monoplaのインストールは完了です。
サンプルプログラムの実行
py-monoplaのsamplesディレクトリのサンプルプログラムを動かしてみます。
SORACOM OnyxをRaspberry Pi 4のUSBポートに挿し「さくらのモノプラットフォーム」に接続した状態にします。続いてインストール時に作成したPython環境を有効にします。
pi@monoplapi:~/py-monopla $ source venv/bin/activate (venv) pi@monoplapi:~/py-monopla $ cd samples/ (venv) pi@monoplapi:~/py-monopla/samples $
オブジェクト送信
このサンプルプログラムでは以下のオブジェクトを送信します。
タグ | タイプ | 値 |
---|---|---|
00 | uint8 | 0 |
01 | int8 | 1 |
02 | uint16 | 2 |
03 | int16 | 3 |
04 | uint32 | 4 |
05 | int32 | 5 |
06 | uint64 | 6 |
07 | int64 | 7 |
10 | float32 | 1.4142135 |
11 | float64 | 2.2360679775 |
20 | float64 | 0102030405(HEX) |
21 | string.utf8 | Hello |
object_tx.pyを実行します。
送信に成功するとOTIDを表示します。
(venv) pi@monoplapi:~/py-monopla/samples $ ./object_tx.py OTID:abaeb782c7394fef805909708f6e3153
受信確認
SIMが所属しているプロジェクトに関連付けられている「さくらのモノプラットフォーム」のサービスアダプタ(WebSocket)の画面で受信を確認します。
受信内容は以下のようになります。
{ “id”: “abaeb782-c739-4fef-8059-09708f6e3153”, “device_id”: “xxxx”, “timestamp_src”: “1970-01-01T00:00:00.000Z”, “timestamp_platform_from_src”: “2023-09-27T08:10:47.473Z”, “timestamp_platform_to_dst”: “2023-09-27T08:10:47.919Z”, “type”: “object”, “payload”: [ { “type”: “uint8”, “tag”: “00”, “value”: 0 }, { “type”: “int8”, “tag”: “01”, “value”: 1 }, { “type”: “uint16”, “tag”: “02”, “value”: 2 }, { “type”: “int16”, “tag”: “03”, “value”: 3 }, { “type”: “uint32”, “tag”: “04”, “value”: 4 }, { “type”: “int32”, “tag”: “05”, “value”: 5 }, { “type”: “uint64”, “tag”: “06”, “value”: 6 }, { “type”: “int64”, “tag”: “07”, “value”: 7 }, { “type”: “float32”, “tag”: “10”, “value”: 1.4142135 }, { “type”: “float64”, “tag”: “11”, “value”: 2.2360679775 }, { “type”: “binary”, “tag”: “20”, “value”: “AQIDBAU=“ }, { “type”: “string.utf8”, “tag”: “21”, “value”: “Hello” } ] }
オブジェクト受信
このサンプルプログラムは「さくらのモノプラットフォーム」にデバイス宛のオブジェクトが存在する場合、受信し内容を表示します。存在しない場合は「Empty」と表示します。
オブジェクトが存在する場合
コントロールパネルのSIMが所属しているプロジェクトに関連付けられている「さくらのモノプラットフォーム」のサービスアダプタ(WebSocket)の画面の「メッセージ送信」からデバイスへ送信します。
※タグ: 0x10、タイプ: uint32、値: 12345678を送信
Raspberry Pi 4でobject_rx.pyを実行します。
(venv) pi@monoplapi:~/py-monopla/samples $ ./object_rx.py OTID: 8dd6ce978dd4459cb6ad9ea0ff80fe18 tag: 0x10 type: SipfObjectType.UINT32 value_len: 4 value: 12345678
受信したオブジェクトの内容が表示されます。
オブジェクトが複数存在する場合
WebSocket簡易UI等からJSON形式で複数オブジェクトを送信した場合、受信に含まれるオブジェクトを列挙して表示します。以下のJSONを送信します。
{ “device_id”: “xxxxxx”, “type”: “object”, “payload”: [ { “type”: “uint8”, “tag”: “00”, “value”: 0 }, { “type”: “int8”, “tag”: “01”, “value”: 1 }, { “type”: “uint16”, “tag”: “02”, “value”: 2 }, { “type”: “int16”, “tag”: “03”, “value”: 3 }, { “type”: “uint32”, “tag”: “04”, “value”: 4 }, { “type”: “int32”, “tag”: “05”, “value”: 5 }, { “type”: “uint64”, “tag”: “06”, “value”: 6 }, { “type”: “int64”, “tag”: “07”, “value”: 7 }, { “type”: “binary”, “tag”: “09”, “value”: “AQIDBAU=“ }, { “type”: “string.utf8”, “tag”: “10”, “value”: “Hello” } ] }
Raspberry Pi 4でobject_rx.pyを実行します。
(venv) pi@monoplapi:~/py-monopla/samples $ ./object_rx.py OTID: e8039b6928c041d891183537a50f4370 tag: 0x00 type: SipfObjectType.UINT8 value_len: 1 value: 0 tag: 0x01 type: SipfObjectType.INT8 value_len: 1 value: 1 tag: 0x02 type: SipfObjectType.UINT16 value_len: 2 value: 2 tag: 0x03 type: SipfObjectType.INT16 value_len: 2 value: 3 tag: 0x04 type: SipfObjectType.UINT32 value_len: 4 value: 4 tag: 0x05 type: SipfObjectType.INT32 value_len: 4 value: 5 tag: 0x06 type: SipfObjectType.UINT64 value_len: 8 value: 6 tag: 0x07 type: SipfObjectType.INT64 value_len: 8 value: 7 tag: 0x09 type: SipfObjectType.BIN_BASE64 value_len: 5 value: b’\x01\x02\x03\x04\x05’ tag: 0x10 type: SipfObjectType.STR_UTF8 value_len: 5 value: Hello
オブジェクトが存在しない場合
受信すべきオブジェクトが存在しない場合object_rx.pyを実行すると
(venv) pi@monoplapi:~/py-monopla/samples $ ./object_rx.py Empty
Emptyと表示されます。
ファイル送信
「さくらのモノプラットフォーム」にファイルを送信します。
送信するファイルを作成します。(内容がランダムな100kBのファイル)
(venv) pi@monoplapi:~/py-monopla/samples $ dd if=/dev/urandom of=~/random_100k.bin bs=1k count=100 100+0 records in 100+0 records out 102400 bytes (102 kB, 100 KiB) copied, 0.00608402 s, 16.8 MB/s
file_upload.pyを実行します。
random.binというFileID(ファイル名)で先程作成したrandom_100k.binをアップロードします。
(venv) pi@monoplapi:~/py-monopla/samples $ ./file_upload.py random.bin ~/random_100k.bin upload /home/pi/random_100k.bin to random.bin upload successful.
アップロードしたファイルの確認
SIMが所属しているプロジェクトの「ファイル送受信」タブを選択します。
random.binという名前で100kBのファイルがアップロードされていることを確認します。
ファイル受信
「さくらのモノプラットフォームから」ファイルをダウンロードします。
ファイル送信でアップロードしたrandom.binをダウンロードします。
FileID(ファイル名)にrandom.binをrandom_download.binという名前でダウンロードします。
(venv) pi@monoplapi:~/py-monopla/samples $ ./file_download.py random.bin ~/random_download.bin download random.bin from /home/pi/random_download.bin download successful.
ダウンロードしたファイルの確認
ファイル送信に使用したrandom_100k.binとダウンロードしたrandom_download.binを比較し、一致するか確認します。
(venv) pi@monoplapi:~/py-monopla/samples $ diff ~/random_100k.bin ~/random_download.bin (venv) pi@monoplapi:~/py-monopla/samples $ sha1sum ~/random_100k.bin ~/random_download.bin 151cc43da9b4d3e85cbc586c2b73e2fb7f78a3bb /home/pi/random_100k.bin 151cc43da9b4d3e85cbc586c2b73e2fb7f78a3bb /home/pi/random_download.bin
diffコマンドで差分が表示されないこと、SHA1のハッシュ値が一致することからダウンロードしたファイルの内容が正しいことが確認できました。
まとめ
以上、「py-monopla」とRaspberry Pi 4で実際に動かす手順のご紹介でした。
「さくらのモノプラットフォーム」を利用するデバイスの例として「開発キット」を提供してきましたが、今回あらたな選択肢を提供することができました。
開発キットと比較してLinux + Pythonで使用できるためマイコンに不慣れな方でも「さくらのモノプラットフォーム」を使いやすくなります。
py-monoplaはまだ生まれたてですので、是非使っていただいてフィードバックをいただければと思います。
特にGitHubへのプルリクエストをいただければ大変うれしく思います。
今回のpy-monoplaを始め、様々なデバイスから「さくらのモノプラットフォーム」をご利用いただけるような発信を続けていきますのでこれからもよろしくお願いいたします。
IoTコラムでは、さくらのIoTに関係するビジネス向けの内容や身近な例、通信技術の説明や当社エンジニアが取り組んだ開発サンプルなどを掲載しています。