ミニマリストのためのIoT開発 〜Cloud Functions とウェビオ で、サーバレスかつハードレス な温度アラートシステムを作る

今回は[IoTLTのアドベントカレンダー](https://qiita.com/advent-calendar/2017/iotlt_neo)のための投稿です。

## ご挨拶  
こんにちは、IoTLTではお馴染み(?)の「しおげん@ウェビオ」です。普段は、IoT専門の受託開発とIoT向けセンシングサービス「[ウェビオ](https://webiot.io/)」をやっております。

## 時代は「サーバレス」
昨年ぐらいから、「サーバレス」なる用語が流行り始めているようです。
Googleトレンドで見てみると、2016年の初め頃からどんどん伸びて、成長中。
![サーバレス.png](https://qiita-image-store.s3.amazonaws.com/0/212269/35613870-81d8-7e66-b27d-acf37a28d9a7.png)

サーバのことは気にせずに、純粋にロジックだけを記述してクラウド上に「関数」としてデプロイしてしまおうという、ミニマリストにはなんとも嬉しい概念であります。AWSのLambdaに始まり、GoogleやMicrosoftも同様のサービスを出してきています。

いいですねー。サーバの事は何も考えずに、純粋にロジックに集中できるって。

## ならばIoTも「ハードレス」で
IoTのクラウド側が「サーバレス」なら、ハードウェア側も「ハード(開発)レス」にしたいと思いませんか？そこで、弊社の センサーas a Service「ウェビオ」 の出番となるわけです。ウェビオは、クラウドに直結された色々なセンサーをレンタルしてくれるサービスです。データを取りたい場所にウェビオのセンサーを置くと、データがHTTPSで、JSON形式で飛んできます。これがあれば、もうハード開発を行う事なく、IoTシステムを構築できるという訳です。

**ウェビオの温度センサー**
![webiot_tmp_photo.jpg](https://qiita-image-store.s3.amazonaws.com/0/212269/6d087774-5a6f-5b0a-a5be-16f6c18765ef.jpeg)

## この記事で作るもの
今回は、サーバレスアーキテクチャを提供するGoogle Cloud Functions と　ウェビオの温度センサーを使って、温度アラートシステムをサーバレスかつハードレスで作って見たいと思います。

具体的には、**温度が30度を超えたら、「暑い！」とメールしてくれる**システムです。

これ自体は何の役にも立たないシステムですが、一定の閾値を超えたらアラートを出して欲しいというニーズは色々あると思うので、記事のネタにして見ました。

## システム構成
ウェビオ(温度センサー)
↓
Google Cloud Functions
↓
SendGrid
↓
メールボックス

## Step 1 ウェビオの入手とセットアップ
https://webiot.io/ から、「ウェビオ温度/湿度/気圧センサー BLEタイプ」と「ウェビオ 3G/LTEゲートウェイ」 を申し込みます。

届いたら、ゲートウェイをコンセントに繋ぎます。

ウェビオコンソール https://console.webiot.io/ にログインして、
データが届いているか確認します。

以上で、ハードウェアの準備は終わりです。

## Step 2 SendgridのAPIキーを取得
Sendgridはお馴染みかと思いますが、メール送信APIです。
https://app.sendgrid.com/ にログインし、
左メニュー「Setting」 > 「API Keys」を開きます。
右上「Create API Key」から今回使うAPIキーを作成し、どこかにコピペしておきます。

Sendgridの準備は以上です。

## Step 3 Google Cloud Functions のセットアップ

https://console.cloud.google.com/ にログインして、
左メニューから「Cloud Functions」を選択します。
上部に出てくる「Create Function」 から関数を作成します。

作る関数はこんな感じです。  (CloudFunctionsの詳細は、公式ドキュメントをご覧ください。)
呼び出しタイプはもちろんHTTPトリガーです。

```
//セキュリティー 設定
const SendgridKey = 'ここにセンドグリッドのAPIキー(良い子はベタ書きしないでね)';
const demo01Key = '自分で決めたランダム文字列'; //パスワードみたいなものをつけておく

// Sendgrid 設定
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(SendgridKey);
const msgTo = ['hoge@example.com', 'fuga@example.com']; //送付先メールアドレス
const msgFrom = 'whobar@example.com'; //送信元メールアドレス

//　関数本体
exports.demo01 = function demo01 (req, res) {
  console.log(req.body);

  if (req.body.key !== demo01Key) {  //パスワードみたいなものをチェック
    console.log('403');
    res.status(403).send('Invalid API Key\n');
    return;
  }
  
  //一応ウェビオID(所定のセンサーかどうか)のチェック
  if(req.body.id==='BTXX00'){
    const temperature = Number(req.body.value);  //文字列を数値に変換

    //30度以上の時だけ
    if(temperature >=30){ 
      const msg = {
        to: msgTo,
        from: msgFrom,
        subject: '暑い！',
        text: '暑い！30度超えてるよ。'
      };
      sgMail.send(msg); //メール送信

      const responseText = 'メールを送信しました\n'+JSON.stringify(msg);
      console.log(responseText);
      res.status(200).send(responseText);
      return;
    }

    //30度以上じゃない時は
    const responseText = 'メールは送信しませんでした\n';
    console.log(responseText);
    res.status(200).send(responseText);
    return;
  }

  //ウェビオIDがおかしい時はスルー
  console.log('何か変です');
  res.status(200).send('OK\n');
};
```
関数が作成できたら、
https://us-central1-hoge-fuga.cloudfunctions.net/demo01  
のような呼び出し用URLができるので、メモります。


## Step 4 ウェビオからCloud Functionsを呼び出す
https://console.webiot.io/ の左から「データ連携」を開きます。
HTTP Post を選択し、
温度センサーを選択し、
設定をしていきます。
URLを先ほど作成したCloudFunctionsの呼び出しURLにして、
BODY JSON には

```
{
  "value":"{{value}}",
  "id":"{{id}}",
  "key":"自分で決めたランダム文字列"
}
```

といった感じで、必要なデータを放り込みます。

以上で完成です　。

## テスト
ウェビオの温度センサーに息を吹きかけ、30度以上にして見てください。
無事、メールが送信されれば完成です！

## まとめ
非常に駆け足での紹介となってしまいましたが、
Google Cloud Functions と ウェビオ を使うことで、
非常に少ない量のコーディングで、IoTシステムを構築できることが、
体感いただけたのではないかと思います。

Let's エンジョイ IoT !