Raspberry PiとPythonでsakura.ioを使ってみる(前編)

はじめに

さくらのナレッジ編集部の法林です。

筆者はさくナレの編集に携わる傍ら、さくらインターネットの各種サービスを社外に紹介する仕事をしています。紹介するサービスは多岐にわたりますが、その中の1つに当社のIoTプラットフォームサービスsakura.ioがあります。sakura.ioはセミナーなどで話をするよりも実際に使ってみてもらった方が理解しやすいだろうということで、体験入門的なハンズオンセッションを多数実施しています。

そんな中で先日、「sakura.ioをRaspberry Piにつないで、Pythonのプログラムで操作するハンズオンセッションをやってほしい」という依頼を受けました。sakura.io体験ハンズオンの内容はかつてさくナレに書きましたが(「IoTの世界に触れてみよう!『sakura.io体験ハンズオン』へのお誘い」)、ArduinoやNode-REDを使って実習しています。それに対して今回は使用する機材やプログラミング言語が異なるので、従来のハンズオンを参考にしながら新たに教材を作成しました。

実はそのハンズオンセッションは新型コロナウイルスの影響で中止になってしまったのですが、せっかく作ったものがお蔵入りになるのももったいないので、教材の中からRaspberry PiやPythonを使ってsakura.ioとデータをやりとりする方法を中心にご紹介します。記事は2本組になっています。

  • 前編(この記事)は、ハンズオンの教材に沿う流れで、ハードウェアの組み立て、sakura.ioの設定、Raspberry PiやサーバにおけるPython環境の構築、サンプルプログラムの実行と結果の確認を行います。
  • 後編では、sakura.ioと通信するプログラムをPythonで書く方法を説明します。もっとも、筆者は今回の教材作成を通してRaspberry PiもPythonも初めて触ったので、「書いてみた」的な内容になります。

システム構成

今回構築するシステムの全体像を下図に示します。システムは、sakura.io、IoTデバイス、サーバの3パートに分かれます。それぞれについて説明します。

システムの全体構成

sakura.io

sakura.ioは、さくらインターネットが提供するIoTプラットフォームサービスです。IoTデバイスとの間はLTE(携帯電話の通信網)を使った閉域網(インターネットとの接続性のない閉じたネットワーク)で通信し、Raspberry Piなどの小型PCやマイコンを通してIoTデバイスとの間でデータを送受信します。一方、Webやアプリとの通信はSSLで暗号化し、WebSocketやWebhookなどのプロトコルを用いてデータを送受信します。このようにして、ともすると脆弱になりやすいIoTシステムをセキュアに、かつ組み込み系の人もWeb系の人も容易にシステムを構築できるのがsakura.ioの大きな特徴です。

sakura.ioの概念図

IoTデバイス

IoTデバイスとして、今回は以下の機材を組み合わせたものを使用します。

  • Raspberry Pi
    Linuxなどが動作する小型のシングルボードコンピュータです。この記事で使用したのはRaspberry Pi 3 Model Bです。
  • sakura.io関連部品
    sakura.ioの通信モジュールを、Raspberry Pi接続用のHATに載せたものです。
  • FaBo
    IoT向けのプロトタイピングツールです。各種機能が実装されたモジュールを線で結合することでIoTハードウェアの試作ができます。今回はRaspberry Pi用のスターターキットを用意し、それに含まれている温度センサーとLEDをRaspberry Pi用シールドに接続して使用します。

FaboのRaspberry Pi用スターターキット (出典:FaBo #003 Starter Kit for RaspberryPi)

※ちなみに、通常のsakura.ioハンズオンでは、FaBoと同種のツールであるGroveを使用しています。今回FaBoを使用したのはハンズオンの依頼元からの指定によるものです。

サーバ

Webやアプリを動かすサーバです。本記事ではさくらのクラウドにCentOS 7.7のサーバを作成して使用しますが、今回説明する内容に限ればインターネットにつながっていてPythonが動くコンピュータであれば何でもよいので、例えばMacやWindowsなどのPCでも結構です。

作業手順の概略

作業の大まかな流れとしては以下のようになります。

  1. Raspberry Piとsakura.ioの設定
  2. FaBoの接続とsakura.ioへのデータ送信
  3. サーバでのデータ受信
  4. サーバからsakura.ioへのデータ送信とLEDの操作

それでは、順を追って見ていきましょう。

Raspberry Piとsakura.ioの設定

はじめに、Raspberry Piとsakura.io通信モジュールを組み合わせて、データをプラットフォームに送信できるようにします。これについては「HAT for Raspberry Pi スタートガイド」という文書に作業手順がくわしくまとめられているので、そちらを参照してください。ここでは作業項目だけを列挙します。

sakura.ioコントロールパネルでの作業

  • sakura.ioコントロールパネルへのログイン(さくらインターネットの会員IDが必要です)
  • プロジェクトの作成
  • 通信モジュールの登録
  • 連携サービスの作成(今回はWebSocketを使用します)

sakura.ioコントロールパネルにてプロジェクトを追加したところ (出典:HAT forRaspberry Pi スタートガイド)

Raspberry Piでの作業

  • HATとRaspberry Piを結合
  • sakura.io通信モジュールの取り付け
  • HAT上のディップスイッチの設定
  • Raspberry Piの起動
  • インターフェースの設定
    ※重要:スタートガイドではI2CをEnableにしていますが、今回はそれに加えてSPIもEnableにしてください。
  • 必要なソフトウェアのインストール
    Raspberry Piをインターネットに接続してから、Pythonと、sakura.ioを簡単に扱うためのライブラリをインストールします。なお、PythonはVer3をインストールしてください。
  • Pythonとsakura.ioの動作確認
    Pythonのインタラクティブシェルにて、sakura.ioモジュールのIDを返すプログラムを実行して確認します。
  • sakura.ioへのデータ送信テスト
    Pythonのインタラクティブシェルにて、sakura.ioにデータを送信するプログラムを実行します。その後、sakura.ioのコントロールパネルにて、送信したデータが届いていることを確認します。

以下はPythonとsakura.ioの動作確認の実行例です。

$ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170124] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sakuraio
>>> from sakuraio.hardware.rpi import SakuraIOSMBus
>>> sakuraio = SakuraIOSMBus()
>>> print(sakuraio.get_unique_id())
16X00000000
>>>

FaBoの接続とsakura.ioへのデータ送信

Raspberry Piとsakura.ioの準備ができたら、FaBoとセンサー類を装着し、温度センサーから出力される温度データをsakura.ioに送信してみます。ここでの作業内容は以下の通りです。

FaBoとセンサー類の装着

まずFaBoシールドをsakura.ioのHATの上に装着し、温度センサーとLEDを下図のように配線します。

下から、Raspberry Pi、sakura.ioのHAT、FaBoのベースシールド

温度センサーとLEDの配線図

サンプルプログラムのダウンロード

Raspberry Piにてターミナルソフトウェアを起動し、GitHubにて公開しているサンプルプログラム集をgit cloneで入手します。

% git clone https://github.com/sakuraio/handson-sample.git
% cd handson-sample/rpi
% ls -1
LINKS.md
README.md
install-devtools.sh
rpi-fabo.py
sakuraio-send.py
sakuraio-test.py
websocket-recv.py
websocket-send.py

サンプルプログラムの実行

サンプルプログラム集の中からrpi-fabo.pyを実行します。これは、温度センサーからデータを取得し、sakura.ioに送信するPythonのプログラムです。以下のような出力が得られれば成功です。

pi@raspberrypi:~ $ python3 rpi-fabo.py
cnt = 0
temp = 22.000000
nothing recv...
cnt=1        ← カウンタ (1ずつアップ)
temp = 23.000000 ← 温度
nothing recv...  ← あとで説明
...

デバイスから送信されたデータの確認

rpi-fabo.pyを実行した状態でsakura.ioのコントロールパネルを見ると、サービス連携画面の下部に、デバイスから送信された温度とカウンタが表示されます(下図)。これで、温度センサーのデータがsakura.ioまで届いていることがわかります。

sakura.ioのサービス連携画面でデータを確認

サーバでのデータ受信

今度は、sakura.ioに届いているデータをサーバで取り出してみましょう。

サーバの作成

まず、さくらのクラウドでサーバを作成します。作成方法はさくらのクラウドのマニュアルをご覧ください。サーバのスペックは最小(CPU 1個/メモリ 1GB/SSD 20GB)で結構です。OSはPythonが動作すれば何でもいいですが、本記事ではCentOSの最新版(執筆時点では7.7)を使用します。

環境構築

sshでサーバにログインし、Pythonと、PythonでWebSocketを扱うためのモジュールをインストールします。PythonはこちらもVer3をインストールしてください。また、下記の実行例に出てくるpip3コマンドはPythonのパッケージ管理ツールで、Pythonをインストールすると同時に導入されます。

% ssh root@<サーバのIPアドレス>
# yum install python3
# pip3 install websocket-client

サンプルプログラムのダウンロード

GitHubにて公開しているサンプルプログラム集をgit cloneで入手します。

% git clone https://github.com/sakuraio/handson-sample.git
% cd handson-sample/rpi

サンプルプログラムの設定

サンプルプログラム集の中から、ここではsakura.ioのデータをWebSocketで受信するプログラム(websocket-recv.py)を使用します。実行する前にWebSocketのURLを設定します。設定するURLは、sakura.ioのコントロールパネルにて連携サービスの編集画面に記載されています(下図)。これをコピーした後、websocket-recv.pyの下記の行の"wss://...."の部分に貼り付けます。

# 【要設定】WebSocketのURI
uri = "wss://api.sakura.io/ws/v1/xxxxxxxx-yyyy-zzzz-xxxx-yyyyyyyyyy"

sakura.ioコントロールパネルのサービス連携画面からWebSocketのURLを入手

サンプルプログラムの実行

Raspberry Piでrpi-fabo.pyを動かしている状態で、サーバにてwebsocket-recv.pyを起動します。以下のような出力が得られれば成功です。

% python3 websocket-recv.py
Receiving...
cnt = 8
temp = 22.000000
cnt = 9       ← カウンタ (1ずつアップ)
temp = 21.000000 ← 温度
cnt = 10
temp = 21.000000
...

サーバからsakura.ioへのデータ送信とLEDの操作

先ほどの例はセンサーからsakura.ioに送られたデータをサーバで受信しましたが、反対にWebやアプリからsakura.ioにデータを送信し、それをIoTデバイスで受信してデバイスを操作することもできます。ここでは、サーバ側のプログラムから値を入力し、その値に応じてRaspberry Piに接続されたLEDを点灯/消灯してみましょう。

サンプルプログラムの設定

サンプルプログラム集の中から、入力された値をWebSocketでsakura.ioに送信するプログラム(websocket-send.py)を使用します。実行する前に設定するのは以下の2か所です。

  • WebSocketのURL
    websocket-recv.pyと同様に、下記の行の"wss://...."の部分に貼り付けます。

    # 【要設定】WebSocketのURI
    uri = "wss://api.sakura.io/ws/v1/xxxxxxxx-yyyy-zzzz-xxxx-yyyyyyyyyy"
    
  • sakura.ioモジュールのID
    sakura.ioのコントロールパネルでプロジェクトに表示されている、uから始まる12桁の文字列がsakura.ioモジュールのIDです(下図)。これを下記の行の"uxxxxxxxxxxx"の部分に貼り付けます。

    # 【要設定】sakura.ioモジュールのID
    module_id = "uxxxxxxxxxxx"
    

sakura.ioコントロールパネルからsakura.ioモジュールのIDを入手

サンプルプログラムの実行

Raspberry Piでrpi-fabo.pyを動かしている状態で、サーバにてwebsocket-send.pyを実行します。すると入力プロンプトとして「>>」が表示されますので、0か1を入力してENTERを押してください(それ以外の入力は無視されます)。1を入力するとRaspberry Piに接続されたLEDが点灯、0を入力すると消灯します。

% python3 websocket-send.py
Sending...
input data: (0=OFF/1=ON/other=NOP)
>> 1
input data: (0=OFF/1=ON/other=NOP)
>> 0
input data: (0=OFF/1=ON/other=NOP)
>> 5
nothing send ... ← 1,0以外の値を入れても何も送信されない

1を入力するとRaspberry Piに接続しているLEDが点灯する

一方、このときにRaspberry Piのターミナルを見ると、websocket-send.pyで1や0が入力されたときはrpi-fabo.pyの出力にled=1やled=0が表示されます。取得すべきデータがないときはnothing recvとなります。

pi@raspberrypi:~ $ python3 rpi-fabo.py
cnt = 100
temp = 22.000000
led = 1      ← LED (1:点灯 / 0:消灯)
cnt = 101        ← カウンタ (1ずつアップ)
temp = 23.000000 ← 温度
nothing recv... ← ledに値がセットされていない (何も受信しない)
...

ハンズオンではこんな実習も

ここまでがハンズオンの教材として作成したPythonプログラムと作業内容ですが、教材では他にも以下の内容を盛り込んでいます。本記事の本題から外れるので詳細な説明は割愛しますが、公開しているハンズオンの資料に手順を掲載していますので、興味のある方はやってみてください。

Node-REDとの接続

通常のsakura.io体験ハンズオンでは、アプリ側のツールとしてNode-REDを使用し、ダッシュボードに温度を表示したり、ボタン操作でLEDを点灯/消灯するという処理を実現しています。今回作成したプログラムにおいても、プログラムとsakura.ioの間で送受信されるデータのフォーマットを従来のハンズオンと同じにしていますので、IoTデバイス側がRaspberry PiやFaBoであっても、従来版と同じNode-REDのフローを使うことができます。

Node-REDのダッシュボード操作の説明スライド

Raspberry Piのインターネット接続を切断

IoTデバイスをインターネットに直接つなぐと、さまざまな攻撃を受けやすくなります。特にIoTデバイスはコンピュータとしては非力なものが多いので、DoSのような攻撃への耐性が低い、セキュリティ関係の重い処理を実装しにくいといった特性があります。

sakura.ioは、IoTデバイスをインターネットに接続せず、閉域網につなぐことでセキュリティレベルの向上を図っています。そこで、今回の実習で使用するシステムができあがったら、IoTデバイスを攻撃から守るためにRaspberry Piのインターネット接続を切断し、その状態でもsakura.io経由でデータの送受信ができることを確認します。

sakura.ioはIoTデバイスのインターネット接続を切断しても動く

続きは後編で

この記事では、Raspberry PiやPythonでsakura.ioを使う方法を、ハンズオンの教材を例に説明しました。具体的な作業としては、Raspberry PiやFaBoとsakura.ioモジュールの接続、sakura.ioの設定、Raspberry PiやサーバへのPythonやライブラリなどのインストール、サンプルプログラムを使ったRaspberry Piおよびサーバとsakura.ioとのデータ送受信の確認、といったところです。

ここまでの説明で、Raspberry PiとPythonを使ってsakura.ioとの通信ができることはわかってもらえたかと思いますが、どうやってプログラムを作ればよいかというところまでは書けなかったので、そちらは後編で説明します。