ABEJA Tech Blog

中の人の興味のある情報を発信していきます

【IoT】SORACOM AirとRaspberryPiで作るインフルエンザ注意報

f:id:hiroyuki_abeja:20170309201833j:plain

はじめに

初めまして。新卒2年目エンジニア、大田黒(オオタグロ)です。主に、ABEJA Platformの開発を担当しています。この記事では、会社で使っている技術について紹介しつつ、簡単なIoTデバイスとアプリケーションのメイキングについて書きます。

モチベーション

デバイスを作り始めた当初(2月)、周囲ではインフルエンザが流行していました。 ちょうどその時、趣味で購入したRaspberryPiとSORACOM AirのSimカード(+モデム)が眠っていたので 何か作ってみようと思い立ちました。

厚生労働省 平成28年度インフルエンザQ&Aによると空気が乾燥すると気道粘膜の防御機能が低下し、インフルエンザにかかりやすくなるとあります。

空気の乾燥を通知することができれば「加湿器を動かす」「マスクを付ける」等のアクションのきっかけを作る事ができ、インフルエンザ対策になります。今回は空気の乾燥を検知し、Slackに自動通知してくれるIoTデバイスを作ろうと思います。

作成物

全体像

f:id:hiroyuki_abeja:20170309091434p:plain Fig.1 「インフルエンザ注意報」のシステム構成

デバイス

役割:特定のデータ(今回の場合は湿度)を取得&加工し、アプリケーション側(後述)にデータ・イベント情報をおくる

今回は、下記の理由から「Raspberry Pi」というARMプロセッサ搭載の小型軽量のボードコンピューターを利用します。

  • 本体の入手性が良い
  • 利用例が多く、資料の入手性が良い
  • 価格が比較的安い
  • センサと融合しやすい
  • LinuxベースのOSが動く
  • USBポート/LANポートが存在

通信ネットワーク

役割:デバイスとアプリケーション間でのデータの橋渡しをする

「どこでも持ち運びができるシステムにしたい!」というコンセプトの元、3G/LTE回線を利用します。 今回は下記の理由からIoT向けのデータ通信サービス(MVNO)として「SORACOM Air」、モデムとして「AKA-020」を利用します。

  • SIMの入手性が良い(最近はAmazonでも手軽に購入できる)
  • SIMの有効化・各種設定が全てWebコンソール上でできる
    • クレジットカードがあればすぐに有効化できる
    • 利用状況をWebから確認できる
  • 細かな設定をAPIから制御できる
  • 閉域網の構築が容易 (今回は使いません)

アプリケーション

役割:データを受け取り、解析・保存・アクションを行う

今回は、アプリケーション構築のためにFunction-as-a-Service(FaaS)の一種である「AWS Lambda」というサービスを利用します。 FaaSを活用すると「サーバ」という管理単位を意識しなくても、アプリケーションを構築することができます。

最近はFaaSを積極的に活用した「サーバレスアーキテクチャ」による開発を行っています。 今回は、業務で使っている技術紹介も兼ねて、アプリケーション部分をAWS Lambdaを使って実装を行います。

  • インフラ環境の整備の必要がなく、開発に集中できる
    • 実行に必要なインフラの準備を行わなくて良い
    • スケーラビリティや可用性の確保を自動で行ってくれる
  • サーバを常に稼働させるより安い
    • イベントの実行回数・実行時間で課金される
  • Python / Node.js / Java等でコーディングできる

参考:サーバレスアーキテクチャという技術分野についての簡単な調査

必要なもの

部品リスト

f:id:hiroyuki_abeja:20170309200006j:plain

TABLE 1 部品表

部品名 型番・性能 入手先
RaspberryPi 3 ModelB 秋月電子 通販コード(M-10414)
スイッチングACアダプタ5V2.5A AD-B50P250 秋月電子 通販コード(M-10507)
ブレッドボード EIC-801 秋月電子 通販コード(P-00315)
3G USBドングル AK-020 SORACOM スターターキット Amazon
湿度センサ TDK CHS-GSS 千石電商 管理コード6A4A-HRFF
A/D変換器 MCP3204 秋月電子 通販コード(I-00239)
高精度温度計 LM35DZ 秋月電子 通販コード(I-00116)
ブレッドボード・ジャンパーワイヤ 秋月電子 通販コード(P-00288)
ブレッドボード・ジャンパーワイヤ(オス-メス) 秋月電子 通販コード(P-03472)

各パーツの役割について

パーツを「ブラックボックス」のまま使いたくない方のために、代表的なパーツの役割・諸元について簡単に説明します。

A/D 変換器(MCP3208)

一般的にセンサとデバイスを接続する時は、センサで計測される温度・湿度といった「物理量」を電圧といった「電気信号」に変換して扱う事が多いです。一方で、電気信号(アナログ)は、デジタル論理で動くコンピューターでは直接扱う事ができません。従って、センサから得た電圧(連続値)をコンピューターで扱えるデジタル値に変換するための「変換器」が必要となります。この役割を持つのがA/D変換器(Analog to Digital Converter)と呼ばれるものです。

f:id:hiroyuki_abeja:20170328005932p:plain:w200

Fig.2 MCP3208のピン配置 (転載元:データシート)

※後述の作成過程において必要になります。印刷しておくと便利です。

今回、A/D変換器としてMCP3208を利用します。MCP3208には以下のような特徴があります。

  • 入力:8本
    • 図中のPin 0〜7を使う事で8本の電圧信号をA/D変換できる
  • 分解能:12bit (4096段階)
    • 基準電圧を用いて4096段階で入力された電圧を表現できる
  • 変換速度:100ksps (電源5V時)
    • 1秒間に100000回のA/D変換ができる (1sps = 1 sample per sec)
  • シリアル・ペリフェラル・インタフェース(SPI)を利用
    • 4本の通信用信号線(図中のPin10,11,12,13)を使い、デジタル信号でデータのやり取りができる
    • 一般的な通信手法であるため、幅広いデバイスと接続できる

温度センサ(LM35DZ)

f:id:hiroyuki_abeja:20170403042803p:plain:w300

Fig.3 LM35DZのピン配置 (転載元:データシート)

今回は温度センサとして、TI社LM35DZを利用します。電源を供給するだけで、温度に比例した電圧が中央のピンから出力される仕組みになっています。従って、前述のA/D変換器に直接接続し、デバイス側で読み込む事ができます。

データシートによると出力電圧と温度の関係は、0 [mv] +10[mV/℃]とあるため、10℃時に100[mV] 、20℃時に200[mV]の電圧が出力されます。 この関係を利用することで、デバイス内部で読み込んだ電圧から温度を計算可能です。

湿度センサ(CHS-GSS)

f:id:hiroyuki_abeja:20170403043626p:plain:w200

Fig.4 CHS-GSSのピン配置 (転載元:データシート)

今回は湿度センサとしてTDK社のCHS-GSSを利用します。このセンサも前述の温度センサと同様で、電源を供給するだけで湿度に比例した電圧が出力される仕組みになっています。湿度センサも同様、A/D変換器に直接接続できます。データシートによると、100%(RH)時に1.0[V]が出力されます。この関係を利用することで、デバイス内部で読み込んだ電圧から湿度を計算可能です。

事前準備

今回作成を進めるにあたり、下記のものが必要になります。

  • SORACOM ユーザーコンソール用のアカウント
  • AWS アカウント
  • HDMIケーブル
  • LANケーブル
  • USBキーボード
  • AWS コマンドラインインターフェイス(aws-cli)
  • Slack API トークン
  • SD <=> MicroSD変換機 (任意)
  • SSHクライアント(任意)

作り方

f:id:hiroyuki_abeja:20170310015011p:plain

Fig.5 作成回路の全体感

Raspberry Piのセットアップ

MicroSDカード作成

f:id:hiroyuki_abeja:20170403045229p:plain:w300

Fig.6 Raspbianのダウンロード画面

Download Raspbian for Raspberry Piより、RaspberryPi用のイメージをダウンロードし、OSイメージをMicroSDカードに書き込んでください。

※環境によってSDカードの作成手順が異なります。Macの方は下記ページを参考にしてください。

参考:Mac OS X で Raspberry PiのOSイメージを焼く

動作チェック

SDカード作成後、RaspberryPiにHDMIケーブル・USBキーボード・LANケーブルを接続し、電源アダプタを接続してください。 電源アダプタを接続すると、RaspberryPi上の緑色LEDが点灯します。

f:id:hiroyuki_abeja:20170328000947j:plain

Fig.7 RaspberryPi 動作時の様子

下記のような画面が出れば成功です。

f:id:hiroyuki_abeja:20170403030421j:plain

Fig.8 RaspberryPi OSブート時の画面

SPI通信の有効化

RaspberryPiをAD変換器に接続するにあたって、SPI通信用のカーネルモジュールを有効化します。 下記のコマンドから、raspi-config(RaspberryPiの設定ツール)を開き、「7 Advanced Options」→「A6 SPI」へと進み、SPI通信を有効化してください。

$ sudo raspi-config

f:id:hiroyuki_abeja:20170403045327p:plain:w300

Fig.9 raspi-config起動の様子

回路作成

この章では、実際に回路構築を行います。配線ミスはデバイスやパーツの故障に繋がるため、慎重に作業を行ってください。

RaspberryPiとA/D変換器の接続

接続対応表
RaspberryPi側端子名 RaspberryPi側ピン番号 MCP3208側端子名 MCP3208側ピン番号 説明
DC Power 5V #02 Vdd #16 電源供給用
DC Power 5V #02 Vref #15 基準電圧供給用
Ground #06 DGND #09 電源供給用
Ground #06 ANGD #14 電源供給用
SPI_MOSI #19 Din #11 SPI通信データ転送用
SPI_MISO #21 Dout #12 SPI通信データ転送用
SPI_SCLK #23 CLK #13 SPI通信クロック供給用
SPI_CE0_N #24 CS/SHDN #10 SPI通信スレーブ選択用

表中のピン番号と物理的なピン配置の関係は下記の通りです。

f:id:hiroyuki_abeja:20170403030837p:plain:w400

Fig.10 Raspberry Pi のピン配置

上記の図は、公式サイトより転載しました。 MCP3208のピン配置はFig.2をご確認ください。

実際の配線方法

実際の配線には、部品表のブレッドボードとジャンパーワイヤを使って接続を行います。 接続対応表・下記の実体配線図を接続を行ってください。

f:id:hiroyuki_abeja:20170403024229p:plain

Fig.11 実体配線図

下記の写真は、配線完了時の様子です。

f:id:hiroyuki_abeja:20170328001105j:plain

Fig.12 実際の接続後の様子

A/D変換器とセンサの接続

今回はMCP3208のCH0(チャンネル0)に温度センサ、CH1(チャンネル1)に湿度センサを接続します。

接続対応表
温度センサ

TABLE MCP3208 <=> LM35DZ 接続対応表

MCP3208側端子名 MCP3208側ピン番号 LM35DZ側端子名 LM35DZ側ピン番号 説明
Vdd #16 +Vs #01 電源供給用
CH0 #01 Vout #02 センサー出力取り込み用
DGND #09 GND #03 電源供給用
湿度センサ

TABLE MCP3208 <=> CHS-GSS 接続対応表

MCP3208側端子名 MCP3208側ピン番号 CHS-GSS側端子名 CHS-GSS側ピン番号 説明
CH1 #02 Vout #01 センサー出力取り込み用
DGND #09 GND #02 電源供給用
Vdd #16 +Vs #03 電源供給用
実際の配線方法

RaspberryPiとMCP3208の時と同様、ジャンパーワイヤを使って接続を行ってください。 CHS-GSSは部品表面にピン配置が書いてありますが、LM35DZは書いてありません。 接続ミスしないように注意してください。

f:id:hiroyuki_abeja:20170403035328p:plain

Fig.13 実体配線図

f:id:hiroyuki_abeja:20170403041541j:plain

Fig.14 実際の接続後の様子

SORACOM Airの準備

大まかな流れは下記のとおりです。

  1. SIMのアクティベーション
  2. SIMのモデムへのマウント
  3. RaspberryPi側の設定

SIMのアクティベーション

f:id:hiroyuki_abeja:20170328023103p:plain Fig.15 SIM登録画面

「SORACOM ユーザーコンソール」にログイン後、「➕SIM登録」を押してください。 上の様な画面が出てくるので、そこに必要な情報を記載してください。 (SIMカードのマウントされているプラスチックの裏側に、IMSI等が記述されています)

SIMカードのマウント

f:id:hiroyuki_abeja:20170328021818j:plain

Fig.16 SIMカードマウント後の様子

アクティベーションが完了したので、SIMカードを利用することができます。このSIMカードをモデムに挿すことで利用ができるのですが、サイズが異なるため、直接挿すことができません。 スターターキットにはサイズ変換用アダプタが同封されています。このアダプタを使い、写真のようにSIMカードをマウントしてください。

PPP接続準備

SORACOM AirのSIMを使いモデムからPPP接続を行うために、wvdialを導入する必要があります。 wvdialはPPP(Point-to-Point Protocol)のダイアラであり、これを使うことで楽にRaspberryPiからPPP発信が可能です。 下記のコマンドからwvdialをインストール可能です。(ejectは後述のスクリプトで利用します)

$ sudo apt-get update
$ sudo apt-get install -y eject wvdial

wvdialのための設定ファイルを生成します。

接続用シェルスクリプトの用意

下記のスクリプトを任意の場所に配置してください。 自動起動スクリプト(/etc/rc.local)から呼び出すため、実行権限を付ける必要性があります。

スクリプトパス例:/home/pi/connect_with_soracom.sh

接続テスト

f:id:hiroyuki_abeja:20170328025547p:plain Fig.17 PPPリンクが確立している様子 (SSH経由で確認)

上記のシェルスクリプトを実行し、ifconfigを実行するとppp0という項目が確認できると思います。 ppp0がしばらく待っても生成されない場合、何かしらの問題が発生している可能性が高いです。

プログラミング(アプリケーションサイド)

この章では、AWS Lambda上で動かすコード(Lambdaファンクション)の作成方法・API経由で呼び出す方法について説明します。 ここからの作業はAWSのWebコンソールからでも可能ですが、最近業務で使っていて便利だったAWS コマンドラインインターフェイス(aws-cli)を使って説明を行います。

CLIの初期設定

$ aws configure

上記のコマンドを実行すると以下4項目が順番に聞かれるので、適切に入力してください。 AccessKeyId・SecretAccessKeyは、AWS Identity and Access Management (IAM)から取得する事ができます。

AWS Access Key ID [None]: xxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxx
Default region name [None]: us-east-1 (ご自身の環境にあわせてください)
Default output format [None]: json

Lambdaを使ったアプリケーションの構築

これから実際にAWS コマンドラインインターフェイスを使ったアプリケーション構築の説明にうつります。 作業手順に登場するREGION,ACCOUNT_IDは、各自の環境に置き換える必要性があります。

Lambdaファンクションの準備

下記のスクリプトは、今回のアプリケーションの中核を担うAWS Lambda上で動くファンクションです。Lambda上のランタイム Python 2.7で動くことを想定して書いています。

スクリプトパス例:<WORK_DIR>/lambda_function.py

※ スクリプト中のSlack用APIトークンですが、事前に取得したAPIトークンに書き換える必要性があります。

本スクリプトでは、SlackClientというライブラリを利用しています。 しかしLambda上ではpipインストールが利用できないので、サードパーティ製ライブラリを直接導入する事ができません。今回は、Lambdaファンクションを必要なライブラリと一緒にZipで圧縮し、Lambdaに登録します。

Lambdaファンクション登録

ここまででLambdaファンクションの準備ができました。次にLambdaファンクションの登録を行います。 大まかな流れは下記のとおりです。

  1. Lambda実行用ロール作成
  2. Lambdaファンクション登録

API Gatewayの設定

前述のLambdaファンクションをAPI経由で呼び出すために、API Gatewayの設定を行います。 今回は下記の前提条件のもと、設定を行います。

  • デバイス側から送信したデータは、POSTメソッドを使いJSON形式でデータを受け取る
  • 今回は認証はもうけない
  • ステージ名はdevとする

大まかな流れは下記のとおりです。

  1. API作成&定義
  2. APIとLambdaの連携・権限付与
  3. APIのレスポンス設定
  4. APIのデプロイ

ここまででAPI Gatewayの設定は完了です。 API Gatewayで作成したエンドポイントは、https://<REST_API_ID>.execute-api.<REGION>.amazonaws.com/<STAGE>/<ENDPOINT>の形でアクセスが可能になっています。

今回の例では、https://ou89mo95s6.execute-api.us-east-1.amazonaws.com/dev/fluReportとなります。

プログラミング(デバイスサイド)

ここまででアプリケーションサイドの構築が終わりました。 ここからは、アプリケーションにデータを送るデバイスサイドのプログラミングを行います。

PiPiperの導入

今回、RaspberryPiからA/D変換器にSPI通信でアクセスする為にPiPiperというライブラリを利用します。 基本的には下記のコマンドで準備が可能です。

$ sudo apt-get install ruby ruby1.9.1-dev libssl-dev
$ sudo gem install pi_piper

計測・データ送信用スクリプト

下記のスクリプトは、RaspberryPi上で動く計測(A/D変換)・データ送信用のスクリプトです。 大まかな処理の流れは以下のとおりです。

  1. SPI通信でA/D変換器と通信し、電圧データを取得する
  2. 電圧データから温度[℃]・湿度[%]を計算する
  3. API Gatewayに送る用のオブジェクトを生成する
  4. API Gatewayにjson形式でデータ送信
  5. 一定時間待つ
  6. 1へ戻る

このスクリプトを実行する事で、定期的に温度・湿度データがアプリケーション側へと送信されます。 スクリプト内の送信先エンドポイントは、前のステップで作成したエンドポイントを指定する必要性があります。

スクリプトパス例:/home/pi/sender.rb

※ このスクリプトはSPI通信を行うため、管理者権限が必要です。sudoを付けて実行する必要性があります。

自動起動化

ここまでで最低限のアプリケーションの用意が終わりました。 最後にPPP接続自動化と計測・データ送信用スクリプトを自動起動する設定を行います。

/etc/rc.localに下記の行を追加してください。

次から電源投入をする事で、自動でAPI Gatewayに計測データが転送されるようになります。

動作風景

f:id:hiroyuki_abeja:20170309201833j:plain

Fig.18 オフィス内にデバイスを設置したときの様子

作成したデバイスを早速で社内でランニングさせました。 上記の図は、デバイス設置時の様子です。

f:id:hiroyuki_abeja:20170309202234p:plain:w200

Fig.19 Slackでの通知の様子

この日は加湿器が電源OFFの状態で暖房が動いていたため極端に湿度が低く、電源を付けたら早速アラートが飛んでいきました。 社内の様子を見ていると、アラートを見た社員が加湿器の電源を入れる・予防マスクを付けるといった狙い通りアクションを実施していることが確認できました。今回のIoTデバイスの運用によって社内のインフルエンザに対する危機意識向上に貢献できたと思います。

記録したデータを可視化すると、以下のような感じになりました。 手元の温度計・湿度計と比較したところほぼ一致していました。計測の妥当性は問題なさそうです。

f:id:hiroyuki_abeja:20170309203905p:plain

Fig.20 温度変化プロット

f:id:hiroyuki_abeja:20170309203916p:plain

Fig.21 湿度変化プロット

感想

業務で得た知識を活かせている

今回使っている「SORACOM Airを用いたデータ通信」や「サーバレスアーキテクチャ」ですが、入社後に業務を通して得た知識であり、業務ではもちろん、趣味の開発でも積極的に利用しています。今まで、Webアプリケーションを構築する時は、

  1. 最初に仮想(物理)サーバを用意
  2. プロビジョニングを実施
  3. ファイアウォールを設定
  4. Nginx等のミドルウェアをインストール
  5. アプリケーションをフレームワークを使って記述
  6. デプロイ
  7. 必要に応じてロードバランサーを配置

といった作業を行っていました。今では、

  1. 必要なインターフェースを定義(API Gateway)・認証設定
  2. 必要なロジックを記述(AWS Lambda)
  3. デプロイ

上記のプロセスで済むので、機能の高速な実装・仮説検証のイテレーションが回るようになっています。

技術的な成長を感じた

実は私は2015年にABEJAに入社したのですが、入社当時はアプリケーション開発に関する知識・経験がなく、開発に必要な知識のインプットから始まりました。(バッググラウンドが生体医工学・電気電子工学だったので….) 1年目は、デバイスからプラットフォームまで開発・運用の実践経験をひたすら積みました。ブログ執筆を通して入社時当時の自分を思い出し、成長できたなと感じる事ができました。

自社プロダクトのバリューの再認識

ABEJA Platformは、Deep Learning を活用し、様々な大量データの取得・蓄積・学習・解析・出力・フィードバックを行うことができる先進的なプラットフォームです。

今回は、社内技術の中身を記事にする都合上、AWS Lambda等を利用したアプリケーション構築を行いましたが デバイスとABEJA Platformを連携させれば、もっと楽にアプリケーション構築が可能です。今回の例でいうと、デバイスと通信ネットワークを用意するだけで、データの取得・蓄積・データの解析・フィードバック(Slackへの通知)をABEJA Platformをおまかせできます。

本記事ではデバイス管理・認証の仕組み・データ管理の仕組みを一切実装していませんが、実際に大量のIoTデバイスの繋がるアプリケーション部分を作るためにはこれらの仕組みを実装する必要があり大変です。これらの仕組みもABEJA Platformにおまかせできるため、エンジニアは本質的なバリューに集中できます。

今回は、デバイスからアプリケーションまでの一通りの実装を通して自社で開発しているプラットフォームのバリューについて改めて理解できました。

最後に

IoT・ビッグデータ・AIをキーワードにバリバリ活躍したい方!! ご興味のある方は以下のリンクより、Wantedlyページをご確認ください。

ABEJAが発信する最新テクノロジーに興味がある方は、是非ともブログの読者に!

ABEJAという会社に興味が湧いてきた方はWantedlyで会社、事業、人の情報を発信しているので、是非ともフォローを!! www.wantedly.com

ABEJAの中の人と話ししたい!オフィス見学してみたいも随時受け付けておりますので、気軽にポチッとどうぞ↓↓