さくらのIoT Platformを軽く体験した話

さくらのナレッジをご覧の皆様、はじめまして。さくらインターネットの松浪と申します。わたくし事ではありますが、業務とは関係なく、さくらのIoT Platformを触る機会があり、その時の内容を社内で1月に共有したところ、関係者の方から「さくらのナレッジで公開してみたら?」との勧めをうけ、この度公開する運びとなりました。

さくらのIoT Platformについては以下のリンク先をご参照ください。

さくらのIoT Platform
https://iot.sakura.ad.jp

社内向けの報告なので結構ゆるい文体ですが、あえてスタイルは変えていません。ただし、掲載にあたり意味が通じにくい、注釈を加えたほうが良いと判断した箇所は編集しています。

なお、この記事は「サーバ運用の知識やプログラムなら少しは精通していて、電子工作には興味があるけど挫折した」という方を主な対象にしています。はい。ものすごく狭いですね。でもいいんです。気にしません。

それではどうぞご覧ください。

きっかけ

かねてから社内のIoT担当である植木さんより「IoTに興味はあるかね」との打診があり、「知識は無いけど興味はあるよ」と答えていたところ「じゃあコレを」ということで、ハンズオンセミナー用に用意しているキット一式を新年早々に借り受けた。

「年も明けたことだし、何か新しいことを始めてみるのも悪くないかな」というよくわからない動機で試してみたところ一応動いたので思い出として残すことに。

開封前の写真を撮り忘れたんで完成後の写真を

入っていたもの

  • さくらの通信モジュール
  • Arduinoシールドボード
  • ブレイクアウトボード
  • Arduino本体(Arduino UNO)
  • USBケーブル
  • ジャンパワイヤー
  • ブレッドボード
  • 人感センサー(SB412A)
  • 温湿度センサー(HDC1000)
  • CdSセル(GL5528?)←照度検知用っぽい

いくつか足りてないけどこんな感じ

慣れてみる

自分は電子工作やIoTといった知識についてほとんど持ち合わせてないので、手始めにArduinoを触ってみる。

「いつか触ろう」と思って購入していたものの半分ほど読んで放置していた本を軽く読み返す。

これ1冊でできる! Arduinoではじめる電子工作 超入門 改訂第2版
https://www.amazon.co.jp/dp/4800711460/

Arduino IDEをWindowsへインストール→Lチカ(LEDをチカチカさせる)で満足。おなかいっぱい。でもArduinoを全く触ったことがないのである意味新鮮だった。

何がしたいか?を考える。

本を読み返してある程度理解はできたものの、「で、どうしよう」と思考が停止する。

目的「ひょっとして私たち」
手段「入れ替わってるー!?」
みたいなことになってしまったなぁと思いつつ、無理やり考えてみる。

・・・・・ (考え中) ・・・・・。

人感センサーに反応したら通知する、みたいなことができれば便利かも?と思ったものの、どうすればいいのか全くわからない。
うなだれていたところ、センサーに「SB412A」て書いてあるのを見つけたので、ググってみるとそれなりにヒット。それなりに安価で小さいのと配線が簡単なためか結構有名なパーツみたい。先人がサンプルコードも載せてくれているので一筋の光が見えた気がする。ありがたやありがたや。

人感センサーを動かしてみる。

やりたいことができたので人感センサーをさっそくArduinoへつないでみる。ブレッドボードへの配線は根拠の無い自信で乗り越えた。とはいえ電源の+と-(VddとGND)は間違えないようにだけ気をつける。壊したら泣けるし。

・・・動くかな?・・・動いた!

んでも、ちょっと敏感すぎやしないかコレ。すぐに反応するのは困るなぁ。

ん?Timeって書いたネジがある。よっしゃ触ってみよう→ずっと反応してるんですけど何これちょうこわい。

ネジをドライバーでくるくる

あとで調べてみると、Timeってのは反応してから持続する時間を表すっぽい。5秒から60秒の間で調節可能らしい。1秒ってできないんですかそうですか。ちょっとでも動くと反応するのはちょっとなぁと思ったので囲いを設ける。もはや電子工作っていうより普通の工作。

普通の工作

さくらの通信モジュールを開封する。

Arduinoを本格的に触るとそれだけで日が暮れそうなんでさっさと次へ進む。
さくらの通信モジュールとArduinoシールドボードを開封しArduinoへ取り付ける。

本体の登録と動作テスト

説明書を見ると本体の登録を済ませないとダメっぽい。なるほど。めんどくさいけど動作に必要なのですね。えぇ。わかりました。プロジェクト名はとりあえずの名称を入力。んんん!?連携サービス??よくわからんけど適当に登録しておこう。

いくつかサービスを登録してみる

あと、Arduinoシールドボードの説明書にはジャンパに関する記述があったものの、正直よくわからない。
しばらく悩んだ後、先の入門書はI2Cが一般的って記述があったことを思い出し、I2Cの配列にしてみる。
使うのかなコレ?

問題のジャンパ

ということで、ArduinoとArduinoシールドボード+さくらの通信モジュールをようやく合体。
サンプルコードも動くようなのでたぶん大丈夫なんだろう・・・。

動けばいいな

※Arduinoシールドボードのピンソケット配列はArduino UNOと同じなので、直上に差しなおしています。

人感センサーと組み合わせる

サンプルコードも動いたので、今度は人感センサーで反応したら送信できるかどうかを試そうと思い、サンプルコードを改良するもうまくいかない。
そういや植木さんから教えてもらったハンズオンセミナー用のプレゼン資料があったことを思い出したので読んでみるも、人感センサーを使っていないっぽい。

ちくしょうあと一歩なのにと落ち込んでいたところ、人感センサーを使ったサンプルがgithubにあるのを見つける。灯台下暗し。

試してみたところあっさり動いた。でも毎秒データを送信するのもアレやし、検知したときだけ送るように変更。

#include 
SakuraIO_I2C sakuraio;
const int ledPin = 13;         // LED接続ピン(定数)
const int analogInPin = A0;    // アナログ入力ピン(定数)
uint32_t  ad;                  // AD値(変数)
uint32_t cnt = 0 ;
void setup(){
  pinMode(ledPin, OUTPUT);     // LEDのピンを出力に設定
  Serial.begin(9600);
  Serial.println("Waiting to come online");
  for (;;) {
    if ( (sakuraio.getConnectionStatus() & 0x80) == 0x80 ) break;
    Serial.print(".");
    delay(300);
  }
  Serial.println("OK");
}
void loop(){
  ad = analogRead(analogInPin);         // AD値を取得
  //Serial.println(ad);
  if ( ad == 0 ) {
    digitalWrite(ledPin, LOW);          // AD値が0ならLEDを消灯
    delay(1000);
  } else {
    digitalWrite(ledPin, HIGH);         // AD値が0以外ならLEDを点灯
    cnt++;
    Serial.println(cnt);
    sakuraio.enqueueTx(1, cnt);
    sakuraio.send();
    delay(5000);
  }
}

Arduinoで動かすためのソース

どうやって通知するかを考える

センサーで検知したことをさくらの通信モジュール経由でIoTプラットフォームへ届けることができたので、次のステップへ進む。

IoTプラットフォームにあるデータはJSON形式で取得できるっぽい。

※後で知ったのですが、この方法は「DataStore (β)」を利用しています。IoTモジュールからIoTプラットフォームへデータを送るだけであれば他にも方法があります。詳細については【公式ドキュメント】をご参照ください。
※「さくらのIoT Platform」および「DataStore (β)」は2017年2月現在、β版としての提供となります。このため、今後仕様が変更となる場合もあります。あらかじめご了承ください。

ハンズオンセミナー用の資料をみると「さくらのクラウド」と連携させてるようなのでそれに倣う。とりあえずサーバを起動し、最低限のアクセス制限を施す(ココ重要)&PHPをインストール。

※「さくらのクラウド」は時間単位で利用できるため、気軽に試せるのが良いところです。

IoTプラットフォームのAPIのサンプルをみるとCurlを使って100件のデータを取得してるけど、そんなにいらんので1件だけ取得。

コントロールパネルからTokenを取得して・・・

APIドキュメントに貼り付けるとヒントが出る!

https://api.sakura.io/datastore/v1/channels?token=トークン&size=1

これで取れそう

ウェブブラウザで見るとこんな感じに

なるほどわからん。でも、valueってところを見ればカウントした数字を取れそうな感じがする。

取ってきたJSONを$arrてのに入れて、$arr['results'][0]['value']って書けば取り出せそうかな?→できたっぽい!

よしこれで完成!検知したらメールを送ればいいかな・・・と思ったけど、Slackで通知しても良いんじゃないかと魔が差す。
Slackよくわからんけどこれもいい経験だと自分に言い聞かせる。

Slack: Where work happens
https://slack.com

(おまけ)Slackで通知する

Slackへ機械的にメッセージを通知したいときはAPIを使えばできるっぽい。

【手順】

  1. ゴミのようなメッセージを送っても怒られないよう、自分用の部屋を作る。
  2. Slackの左上のメニューから「Customize Slack」→「Configure Apps」→「Custom Integrations」→「Incoming WebHooks」→「Add Configuration」→「Post to Channel」の順に辿り、メッセージを投げたい部屋の名称を入力。
  3. 「Webhook URL」にある文字列(https://hooks.slack.com/services/から始まるアレ)を送信したいサーバから送る。

あと、↓がかなり参考になった(ていうかサンプルをほぼほぼいただく。拝)

PHPでSlackにメッセージをポストするクラスのサンプル - Qiita
http://qiita.com/monhan/items/d95ad6e4e698da9e6593

で、いただいたソースをごにょごにょして完成。↓みたいな感じで。

<?php
include_once __DIR__.'/SlackBot.php';
include_once __DIR__.'/SlackBotInfo.php';
ini_set('mbstring.internal_encoding', 'UTF-8');
$json_url = 'https://api.sakura.io/datastore/v1/channels?token=トークン&size=1';
function getJson($arg){
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $arg);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
  $json = curl_exec($ch) or die('read error');
  curl_close($ch);
  $arr = json_decode($json, true);
  $ret = ($arr['results'][0]['value']);
  return $ret;
}
$cnt = getJson($json_url);
while(1){
  sleep(5);
  $cnt_tmp = $cnt;
  $cnt = getJson($json_url);
  if($cnt !== $cnt_tmp){
    $message = "こんにちは!あなたは $cnt 番目のお客様です!";
    $url = 'https://hooks.slack.com/services/謎の文字列';
    $bot = new SlackBot();
    print_r($bot->post_message(new SlackBotInfo($url, $message)));
  }
}

さくらのクラウドに置くスクリプト

【ちょっと解説】
5秒ごとにIoTプラットフォームのJSONを1つだけとってきて、valueに変化があればSlackへ通知してる

※SlackBot.php および SlackBotInfo.php は適宜ご用意ください。

※冷静に考えると「こんにちは!あなたは $cnt 番目のお客様です!」という表現はおかしいのですが、当時は「動きゃ良いんだよ動きゃ」程度のノリで作成していました。

こんな感じで届いた!

届いた!

まとめ

必要な知識は以下のような感じ。ぜんぜんまとまってないけど、そこは想像でカバー

  • Arduinoの基礎的なところ
    • Arduino IDEの使い方(シリアルコンソールの開き方とかマイコンボードへの書き込みとか)
    • Arduinoの言語のお作法(setupとかloopとか)
  • 電子工作の基礎的なところ
    • 電源(Vdd(+)とGND(-))の扱い
    • ブレッドボードのしくみ
    • GPIOを通じた操作
  • 説明書を読む根性
    • Git上にあるソースの取得方法
    • ライブラリをArduino IDEへインクルードする方法(サンプルコードの利用方法も含む)
    • API越しに取得できるJSONへのアクセス方法
  • 自分なりにアレンジできる想像力
    • 得意な言語(なんでも良いからひとつ)
    • サーバ構築(ファイアウォール設定やら)

製作期間:2日(2017/01/05 - 2017/01/06)

追記

【配線について】

(2017/01/10)冷静に考えると、配線はもうちょいシンプルでもよかった感じ

(2017/01/11)写真とってみた

ちょっとスッキリ(ただし机は別)

※もっとシンプルにできます。

【電源について】

(2017/01/10)せっかく作ったんで遠隔から試そうとして、USB接続用のACアダプタを接続してみたものの、なぜだか動かない。電源容量が足りんのかな?説明書を見ると3.0A必要と書いてある。iPad用のACアダプタなら行けるかな?とか早とちりしていたんで後日使えそうな電源を用意しよう。

(2017/01/11)自宅からNexus7用とAnkerのACアダプタを持ってきたところ、動いたっぽい。ついでに昨日ダメだったiPad用のACアダプタでも動いた。なんでやねん。

どれでもOK

【見た目について】

(2017/01/11)基盤むき出しやとオタク感丸出しやなと思っていたところ、休憩室に過去の遺産(ピンク色のブロック)が目に入ったので拝借した。

イイね!(個人の感想)

おわり

さいごに

いかがでしたでしょうか。

ちなみにこのサンプル、人が居なくてもなぜか反応する時があるんですよね・・・。センサーをもう少し高性能なものに変えれば解決するかもしれないのですが、おカネもかかるし今回はサービスに慣れることが目的だったんでこれで終わりにします。

また、このサンプルは工夫次第で「実家に居る親の気配を察知して、n日以上察知できなければ通知する」、「離れの倉庫に置いて番犬代わりに」と言った感じにしたり、通知先をTwitterやLINEに変更するなど、いろいろ応用できそうです。

この記事を見て「さくらのIoT Platformって面白そう!ちょっとやってみようかな」と思っていただければ幸いです。