sakura.io＆Arduinoで作ったIoTデバイスをTwilio Functions経由で制御する

# はじめに
この記事は[Twilio Advent Calendar 2017](https://qiita.com/advent-calendar/2017/twilio)の12月14日の記事となります。

初めまして！さくらインターネットの西田です。
普段は技術や開発というよりはサービス全体のPR活動（ブース出展、ハンズオン講師、広告出稿、プレリリ等）を担当しています。

TwilioはFunctionsで簡単に動作を定義できるうえ、後述するsakura.ioと同様にWebhookの口を持っていることでダイレクトにデータを送り込むことができ、まさにサーバレスでデバイスと電話というインタフェースを繋げることができるというメリットがあります。

## sakura.ioとは？
sakura.ioはさくらインターネットが提供しているIoTプラットフォームサービスです。

一般的にIoTプラットフォームサービスというとクラウド上に構成されたものを指し、そこにデータを引き込む方法は回線、通信方式、バックエンド等々、数ある中から取捨選択して選ぶ必要があり、かつサービス間の責任分界点を丁寧に線引したり、割り切ったりしながらインテグレーションしていく必要がありました。

sakura.ioでは、デバイス側に組み込まれるモジュールをプラットフォームと一体で提供することで、まるでデバイスとデータセンタを直結したようにプラットフォームと接続されるだけでなく、デバイス（マイコン）側から従来使われてきたI2CやSPIといった規格で専用のモジュールにセンサデータを投げ込むだけで、モバイル閉域網（携帯と同じ回線なのにインターネットを経由しない網）を経由してクラウド側へ安全にJSON形式のデータとして複数の方式で取り出せるようになっています。

## この記事のゴール
今回のゴールはマイコン側に温湿度センサとsakura.ioモジュールを繋げ、さらにsakura.io側のOutgoing WebhookとIncoming Webhookを繋ぎこみ、Twilio Functionsに仕掛けたプログラムで自動音声応答を起動、入電を受けた利用者のキー操作に応じてデバイスを制御する、というところまでの実装をゴールとします。

この構成が無事完成すると、以下のような動作を実現できます。デバイスは通電とともに自動的にプラットフォームに繋がり、かかってきた電話に対して操作するだけで制御ができるようになるため、ITに不慣れな方にとても使いやすいサービスを実現できるのではと思います。
普段中々触ることが少ないマイコンに関する解説が長くなってしまいますが、是非ビジネスのアイデアとしてご覧いただければ幸いです。

![図4.png](https://qiita-image-store.s3.amazonaws.com/0/217223/33bd9a1e-5afa-ecc0-0ba7-32ad6d8fc3f1.png)


# 具体的に構築してみる
それでは、早速段階を追って構築を進めていきます。本記事では、大まかに以下の順で進めていきます。
1と2がかなりのボリュームとなってしまいますが、是非ご覧いただければと思います。

1. sakura.ioの設定
2. マイコンおよびプログラムの構築
3. Twilio Functionsの構築 

## sakura.ioの設定
sakura.ioの設定は大まかに「プロジェクト」「モジュール」「連携サービス」という3つに分類され、プロジェクトの中に「複数のモジュール」「複数の連携サービス」「単一のオプションサービス」が所属します。

![図1.png](https://qiita-image-store.s3.amazonaws.com/0/217223/ca989cca-9299-9502-62fa-0bdb0a4bd4a2.png)

利用者は、例えば「IoT照明」のようなプロジェクトを作成し、そこに複数のsakura.ioモジュールを紐付け、さらに用途に併せてWebhookやMQTTといったデータの連携方法を作成することで、データの渡し先を設定していきます。

オプションサービスはまさにオプションで、データの保存場所をよりマッチしたポリシーにしたり、簡易的なデバイスの位置情報をJSONデータとして取り出せるようにしたり、プラットフォーム側からモジュール側にファームウェア配信等に使用するバイナリファイルを指定したり、といっったものを指定します。

### プロジェクトの作成
[会員IDを作成](https://secure.sakura.ad.jp/signup3/member-register/input.html)し、[sakura.ioのコンパネ](https://secure.sakura.ad.jp/iot/login)にログインのうえ約款同意するとこのような画面にたどり着くかと思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/508c113c-6b45-606b-7802-cd13b088842f.png)

元々デフォルトのプロジェクトができているかもしれませんが、一旦新規にプロジェクトを作成してみましょう。
［プロジェクト追加］をクリックします。

プロジェクトの名前だけ指定する必要がありますので、適当な名前を入力し、［追加］をクリックしましょう。
今回はtwilioで作成してみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/66797451-d001-9864-4a34-862867006252.png)


### モジュールの登録
次にモジュールを登録します。今回使うsakura.ioモジュールは[ココ](https://sakura.io/product/)から好きな場所で購入して入手しましょう。

作成したプロジェクト内の［モジュール登録］をクリックし、登録用ID、登録用パスワード、名称、プロジェクトを指定します。登録用のIDとパスワードはモジュール上面の白ラベルにIDとPASSの表記で記載されていますのでこちらを入力します。
4つの項目を全て指定して［追加］をクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/a6643b86-9b58-fd8f-0ec2-187a4f3fbf3a.png)

無事に登録が完了すると「モジュールと追加しました」というメッセージが表示されます。正式版のモジュールを開封して初めて登録すると、その会員IDには検証用等のおまけとして1万ポイントが付与されます。ポイントは通信を行った際に消費されていくのですが、詳細はまた違う機会にお話できればと思います。

ホームに戻り、自身のプロジェクトに先程入力した名称のモジュールが追加されていれば成功です。
プロジェクト上に表示されているIDは入力したものと違い、プラットフォーム側（外部のシステムから）制御信号等を送りつける場合に指定する一意のIDとなります。
なお、今回名称はテストモジュールで登録してみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/908abcd4-50f2-c5a8-66f9-2d54cf5f9b9b.png)

### 連携サービスの追加（Incoming Webhook）
次にデータの連携を行うWebSocketを作成します。作成したプロジェクト内の［サービス追加］をクリックすると現状選択できる連携サービスのラインアップが表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/f05394b9-81a9-7fd1-8cdf-111fab3676c4.png)

今回はOutgoing WebhookとIncoming Webhookが必要なのですが、この時点ではまだTwilio側のエンドポイントとなるURLが定まっていないので一旦Incoming Webhookだけを先行して作成します。

［Incoming Webhook］をクリックし、名称だけ指定して［作成］をクリックするとサービスが作成されます。Secretの値は今回指定しません。
今回はTwilio Incomingという名称で作成しました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/e0e285a2-d8d5-c180-5653-afc2690b4f4c.png)

なお、Secretの値を指定しておくと外部のシステムからX-Sakura-Signatureで指定した値と照合し、HMAC-SHA1で生成されたハッシュ値が合致している場合だけデバイスに送信するというセキュアな運用も可能になります。

以上でsakura.io側での設定はほぼ完了です。Outgoing Webhookの作成についてはTwilio Functionsの構築で追って説明します。


## マイコンおよびプログラムの構築
次に、汎用的なマイコンボードであるArduino Uno、温湿度センサSHT31、さくらで提供しているArduino接続用のシールド等を使って、30度を超えたらsakura.ioに温度情報を送信するデバイスを構築します。

必要になる物品を秋月電子通商では以下のものを選択すると購入できます。sakura.ioモジュールと合わせると2万円弱となります。
[sakura.io シールド for Arduino](http://akizukidenshi.com/catalog/g/gM-12195/)
[Arduino Uno Rev3](http://akizukidenshi.com/catalog/g/gM-07385/)
[USBケーブル Aオス-Bオス](http://akizukidenshi.com/catalog/g/gC-07605/)
[ブレッドボード](http://akizukidenshi.com/catalog/g/gP-05294/)
[温湿度センサ（SHT31）](http://akizukidenshi.com/catalog/g/gK-12125/)
[抵抗内蔵LED](http://akizukidenshi.com/catalog/g/gI-06245/)
[ACアダプター](http://akizukidenshi.com/catalog/g/gM-07772/)
[ジャンパコード](http://akizukidenshi.com/catalog/g/gC-05159/)

### Arduino IDEのセットアップ
まずはArduinoのスケッチ（Arduino上のプログラムコードのこと）を作成、書き込みするため、無償で使用することができる開発ツールをインストールします。カンパも可能ですが、無償で使用することもできます。大事なことなので2回言いました。

[Arduinoのサイト](https://www.arduino.cc/en/Main/Software)から自身のOSのインストーラをクリックし、次の画面で［JUST DOWNLOAD］をクリックすることでインストーラを入手できます。

インストールは基本的に全てデフォルトです。Windowsの場合ドライバのインストールも確認されますので、ホイホイ全てのドライバをインストールしていきましょう。インストールが終わってArduino IDEを起動すると、数行だけ用意されたほぼ空のスケッチが表示されるかと思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/6ee20e20-9cf4-9332-018e-e4f158075315.png)

### ライブラリの入手
汎用のマイコンボードとは言え、イチからスケッチを作っていくのは大変なので、センサ等のモジュール化されたものは用意されたものを利用したいと思います。

［スケッチ］ → ［ライブラリをインクルード］ → ［ライブラリを管理…］と進めるとライブラリマネージャという画面が起動します。ライブラリマネージャはメーカや有志が作成したライブラリを検索、取り込みができるツールになっています。 

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/c814eeac-f67e-5e3e-2dbc-24ed34acacb7.png)

右上の［検索をフィルタ…］という欄で検索ができますので、以下の2つのライブラリを取り込みます。
検索でヒットしたものをクリックし、［インストール］をクリックすることでライブラリが取り込まれ、「INSTALLED」が表示されます。

 * Adafruit SHT31 Library by Adafruit バージョン1.0.0
 * SakuraIO by SAKURA Internet Inc. バージョン1.1.3

### 配線とテストプログラムの書き込み
準備ができたので、マイコンとの配線とテスト用のプログラムを書き込んでいきましょう。
[取扱説明書](https://sakura.io/developer/pdf/sco-ard-01_manual_latest.pdf)を参考に以下の形になるように組み立てます。

 * sakura.ioモジュールにアンテナを取り付ける
 * アンテナを取り付けたモジュールをシールドに組み付ける（コネクタで噛み合うようになっています）
 * 付属のジャンパ（2mm程度の黒いパーツ）2個をI2Cピン選択ジャンパに取り付ける
 * シールドとArduino Unoをピンが噛み合うように組み付ける

最終的にはこのような形になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/0378c6a4-16df-c95e-c23b-9c1afc5f19dd.png)

次に、以下の配線を参考に、計8本の配線を行います。（図ではArduino Unoですが、実際は組み付けたシールド側から配線します）

![図5.png](https://qiita-image-store.s3.amazonaws.com/0/217223/b4f8071d-d003-f6e8-05da-1b25a6f97954.png)

配線が完了したら、USBケーブルでPCとArduinoを接続した状態で以下の2点を設定します。

 * ボード：［ツール］ → ［ボード:”XXX”］ から［Arduino/Genuino Uno］を選択します。
 * シリアルポート：［ツール］ → ［シリアルポート］ から［COMx（Arduino/Genuino Uno）］となるものを選択します。

Win環境の場合はCOMxで表示されますが、Mac環境の場合は/usb/...（Arduino/Genuino Uno）といったデバイスファイルのような形で表示されるものを選択します。こうすることでスケッチで記述したコードが接続したArduino Unoに書き込めるようになります。

Arduino IDEに戻り、[ココ](https://github.com/sakuraio/handson-sample/blob/master/arduino/twilio-SHT31-with-LED.ino)の内容をスケッチに丸々転記し、書き込み（→マーク）をクリックすると、記載されている内容が書き込まれます。

「ボードへの書き込みが完了しました。」とスケッチ下部に表示されたら、シリアルモニタ（虫眼鏡マーク）をクリックすると、スケッチで定義されたプログラムが動作していることが確認できます。

ちなみに、このスケッチの内容では、温湿度センサが検知する温度（Temperature）が30度を超えた時だけ、シリアルモニタに「* Sent to sakura.io *」のメッセージを出力したうえでsakura.ioにデータを送信するようになっています。

```
Waiting to come online
1
Temperature: 24.20
Available :32 Queued :0
2
Temperature: 24.22
Available :32 Queued :0
3
...
..
.
123
Temperature: 30.94
* Sent to sakura.io *
Available :32 Queued :0
...
..
.

```

ちなみに、この流れとは別でsakura.io側にWebSocketの連携サービスを作成しておくと「* Sent to sakura.io *」のメッセージのタイミングでデバイスからのデータが送信されていることを確認できるはずです。

これで下準備は全て完了です。いよいよTwilio側の操作に入ります。

## Twilio Functionsの構築
ここからの作業は当然ながらTwilio側のアカウントが必要となりますので、[Twilioのトップページ](https://twilio.kddi-web.com/)からサインアップでアカウントを作成いただく必要があります。

アカウントをお持ちであれば[Twilioのコンパネ](https://jp.twilio.com/login/kddi-web)からログインをします。

### 電話番号の購入
まずはTwilio側から電話をかけるため、必要となる電話番号を購入します。
左側メニューの［All Products & Services］→［電話番号］→［Buy a Number］と進みます。
番号を購入画面で［Japan(+81)］を選択し、［検索］をクリックすると使用可能な番号一覧が表示されますので、今回は安いTYPEが［ローカル］のものの中から好きなものを選び、購入します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/d8d92ab2-3009-48be-d1a3-69f14d3e79aa.png)

### Functionsの設定（環境変数）
次に、Functionsのプログラムで使用する環境変数の設定を行います。
まずは事前にプログラムに使用する環境変数を指定するため、メニューから［Runtime］→［Functions Beta］→［Configure］と進みます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/7d9abc8a-0ef3-2146-fb9f-f36f110c02a2.png)

Configuration画面では、［Enable ACCOUNT_SID and AUTH_TOKEN］にチェックを入れ、さらにEnvironmental Variables欄に以下の4つの項目を設定します。

 * FROM_NUMBER ： 先程購入した電話番号（E.164形式）
 * MODULE_ID   ： sakura.ioのコントロールパネルで確認したモジュールの一意のID
 * SAKURA_URL  ： sakura.ioのコントロールパネルで生成したIncoming WebhookのURL
 * TO_NUMBER   ： ご自身で通知先として使用したい電話番号（E.164形式）

設定できたら最下部の［Save］をクリックして設定を保存します。下部のDependencies欄の設定は不要です。

### Functionsの設定（プログラム）
次に、Twilio側での動作を定義する3つのプログラムを作成します。
Functions内の［Manage］に移り、新しいプログラムを作成するため［＋］をクリックします。
テンプレートはなんでも良いので、［Create］を選択し、以下の内容に従い、3つのプログラムを設定＆コピペしSaveします。

 * [outboundcall.js](https://github.com/sakuraio/handson-sample/blob/master/twilio/outboundcall.js)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/2122444d-816a-dc1d-25b7-d93949dd8085.png)

 * [ivr.js](https://github.com/sakuraio/handson-sample/blob/master/twilio/ivr.js)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/843fc99d-53dd-255b-14dc-4e4a17ef53f6.png)

 * [turn.js](https://github.com/sakuraio/handson-sample/blob/master/twilio/turn.js)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/e21f4e24-f35b-59e0-5eb4-c569d631bdbd.png)

### 連携サービスの追加（Outgoing Webhook）
最後に、先程投げ込み先となるURLが生成されていなかったので先送りしていた、sakura.ioのOutgoing Webhookを作成します。

作成したoutboundcallプログラムを開き、パス部分を丸々コピーします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/217223/5b899866-fcbf-647b-b617-8f08886771a9.png)

sakura.ioのコントロールパネルで［サービス作成］→［Outgoing Webhook］を選択し、Payload URLにコピーした内容をペーストし、［作成］をクリックします。

今回はTwilio Outgoingという名称で作成しました。

# 動作確認
以上で構築は完了です、早速動作テストをしてみましょう。
温湿度センサの先端部分を指等で押さえて温めると、しばらくして設定した番号に電話がかかってくることが確認できるはずです。

動作の順序としては以下のとおりです。

1. まず、取得された温度データが30度を超えると、Arduinoはシリアルモニタで［* Sent to sakura.io *］というメッセージを出力するとともにデータをモジュールの送信キューに格納し、sakura.ioに送信します。

2. データは安全な閉域網を経由してsakura.ioに送られ、連携サービスであるOutgoing Webhookを介してTwilio Functionsに指定されたホストの/outbound-callに転送します。

3. Outbound-callプログラムから購入した番号（TO_NUMBER）を使い指定した連絡先（FROM_NUMBER）に架電します。

4. IVRプログラムで対応者のキー操作を受け付け、TURNプログラムで指定したキー操作に応じて制御用のJSONデータを生成し、sakura.ioのIncoming Webhook（SAKURA_URL）に送信します。

5. sakura.ioでは受け取ったJSONデータに含まれるモジュールID（MODULE_ID）を元に対象となるモジュールにデータを送ります。

6. Arduinoがモジュールの受信キューからデータを取り出し、スケッチで定義された内容に従ってLEDを点灯させます。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/217223/8f90cb8f-3d6e-64ed-aa13-0c2f4afeaf48.png)

# まとめ
いかがだったでしょうか？
このように、モノからデータを吸い上げるsakura.ioと電話との豊富なインターフェースを持つTwilioを組み合わせることで、今まで接続やアプリケーション利用といったITの取扱に不慣れだったご年配の方を中心に、技術を意識せず、電話やSMSといった馴染みのあるインタフェースを使ってサービスを利用することができるようになります。

今までクラウドサービスはあくまでもWebの中で完結する仕組みの中で利用されてきましたが、昨今のMVNOの普及等の後押しもあり、物理デバイスを起点や終点とした、より現実世界に根ざしたサービスにもライトに活用できるようになってきました。

その中でも使う人を選ばない「電話」というツールを繋ぐことができる「Twilio」はとても素晴らしいサービスだと思っています！
是非みんなで新しいビジネスを生み出していきたいですね！