7
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Google Cloud Functions で obniz を 1分おきに動かしてみた

この記事は obniz Advent Calendar 2019 の11日目の記事です。

obniz で高頻度なセンシングをラクに実現してみたい!

今年の首都圏を襲った台風をきっかけに、 obniz で自宅の気温や気圧などのログを取って可視化してみたいと考え、obniz Cloud の12分おきのセンシングではもの足りず、 Google Cloud Functions で obniz を 1分おきに動かしてみました。

obniz とは

obniz(オブナイズ)は日本の CambrianRobotics 社が開発したマイコンボードで、Wi-Fi に接続してインターネット経由で操作します。簡単に Wi-Fi に繋がり、ファームウェアの書き込み不要で API 経由で操作するので、インターネットと連携したハードウェアをサクッと作れるのが特徴です。

obniz の動かし方

obniz の動かし方の種類

obniz の動かし方は以下のように分類することができます。

obniz を1分おきに動かしてセンサの値を記録したい

obniz サーバーレスイベントは?

obniz サーバーレスイベントを使えば、定期的にセンサの値を記録するようなアプリケーションを作成することができます。ただ、 各イベントの実行は1日に120回まで という制限があります。一定間隔で実行しても12分に1回実行できるわけで、IoTセンシング用途としては十分だと思いますが、 もっと高頻度なセンシングをラクに実現してみたい! ということで、別の方法を調べてみました。

専用のPCやサーバーを用意する?

Raspberry Piなど常時起動できるPCを1台用意して、定期的に走るように設定する方法もありますが、常に起動しておく必要があり、万が一エラーが起きてシャットダウンされた場合、復旧するのが面倒そうです。

FaaS

そこでクラウドサービスを利用することを検討しました。Node.js で数十秒間の関数を定期的に実行したいとなると、FaaSと呼ばれる、イベント駆動型コード実行サービスを使用するのが、容易で適していそうでした。
例えば Google Cloud Functions では、既にNode.js を動かせる環境が入っているため、環境設定が記載されたファイルや、実行する関数が記載されたファイルをアップロードするだけで、クラウド上で実行できるのです。

obniz 公式サイトにも、AWS Lambda で obniz を動かすレッスンがありますが、今回は無料制限回数が多かった(上無料体験期間が残っていた) Google Cloud Functions を使用してみました。
料金 - Google Cloud Functions によると月200万回、100万秒、5GBまで無料で実行できる?ようです。
毎分実行しても1ヶ月に5万回未満なので、無料の範囲に収まりそう…?
(その他の部分で料金がかかるかもしれません。この記事を参考にして生じた損失に関して一切の責任を負いません。)

作るもの

Google Cloud Functions を使用し、 obniz を1分おきに動かしてセンサの値を読み取り、Google Spreadsheet に記録します。測定する量は、温度、湿度、気圧、照度とします。
https://qiita.com/y-hira/items/b8fe1268a12492bd865c
の記事のように、obniz のセンサの値を Google Spreadsheet に記録することができます。

手順

手元のPCで Node.js で obniz を動かすプロジェクトを作成し、 ZIP ファイルに固めて Google Cloud Functions にアップロードする流れになります。macOS 10.13 にて行いました。

obniz に配線

今回は BME280 とアナログ照度センサを配線しました。
image.png

ついでにテレビやエアコンの操作用に赤外線LEDも配線してありますが(笑)

データ記録用のスプレッドシートを作成

https://qiita.com/y-hira/items/b8fe1268a12492bd865c
の手順に従って、スプレッドシートと、GAS のプロジェクトを作成しました。GAS のプロジェクトの「現在のウェブアプリケーションのURL」をメモしておきます。

Node.js と npm をインストール

まず、手元の PC で Node.js と npm を使えるようにしておきます。

Node ファイルの作成

適当なフォルダ(ここでは obniz_gcf) を作成し、 obniz のライブラリをインストールします。

mkdir obniz_gcf
cd obniz_gcf
npm init

npm init では簡単な質問に答えていくと package.json が生成されます。デフォルトのままで良ければ Enter を押していくことで進めます。

npm install obniz

obniz のコードを書くファイル index.js を作成します。

touch index.js

コードを作成

POST するために、慣れているjQuery を使いたかったので、NodeJSでjQueryを使う を参考にコードを作成しました。

index.js
var Obniz = require("obniz");
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
const dom = new JSDOM(`<html><body><div id="aaa">AAA<div></body></html>`);
const { document } = dom.window;
const jquery = require('jquery');
const $ = jquery(dom.window);

exports.handler = function (event, context, callback) {
    var obniz = new Obniz(process.env.OBNIZ_ID);
    const url = process.env.POST_URL;
    var sensor;

    obniz.onconnect = async function () {
        obniz.io8.output(true);
        sensor = obniz.wired("BME280", { gnd: 9, sck: 10, sdi: 11, address: 0x77 });
        await sensor.applyCalibration();
        const illum = await obniz.ad7.getWait();

        const obj = await sensor.getAllWait();
        var param = { sheet: "log", obniz_id: obniz.id, temperature: obj.temperature, humidity: obj.humidity, pressure: obj.pressure, illuminance: illum };
        console.log(param);
        $.post(url, param)
            .done(function (data) {
                console.dir(data);
                obniz.close();
                callback(null, "success");
            });
    }
};

追加で使用するライブラリもインストールします。

npm install jquery
npm install jsdom

Google Cloud Functions にアップロード

ZIP に圧縮

解凍したときに index.js がトップの階層に来るように ZIP に圧縮します。

zip -r obniz_gcf_codes.zip index.js node_modules/ package-lock.json package.json

Google Cloud Platform のコンソール で新たにプロジェクトを作成し、 Cloud Functions のメニューから新たに関数を作成します。

image.png

定期実行の設定

1分ごとに実行するため、トリガーには Cloud Pub/Sub を選択します。
「新しいトピックを作成」し、適当な名前を付けます。
Cloud Scheduler を開き、「ジョブを作成」します。トピックには先程作成したトピック名を指定してください。毎分実行したい場合は、頻度として * * * * * を指定します。その他の時間間隔もこの文字列次第で設定することができます。

image.png

image.png

Google Cloud Functions の設定

ソースコードは ZIPアップロード とし、さきほど圧縮してできた ZIP ファイルを選択します。
実行する関数は handler です。

image.png

また追加の設定項目を開き、環境変数として、 OBNIZ_ID に obniz の ID, POST_URL には GAS アプリケーションのURLを指定します。

image.png

最後に デプロイ !
アップロードに少々時間がかかるかもしれません。
うまくいけば、1分おきに、関数の実行が開始されます!
スプレッドシートを確認して、センサの値が正しく記録されているか確認してみましょう!

約2ヶ月間動かしてみた結果

既に2ヶ月近く動かしているのですが、安定して実行できています。 obniz はコンセントに挿した USB - AC アダプタに挿しっぱなしです。万が一停電が起きても、復旧時にも特に何もする必要がないのが楽でいいですね。

Google Cloud Functions の記録

obniz を接続している Wi-Fi ルーターがもともと不安定でときどき再起動してしまうこともあり、ときどきタイムアウトしていますが、おおむね安定して実行できているようです。Google Cloud Functions の設定では、50秒でタイムアウトとなっています。

image.png

どうやらタイムアウト時間の50秒近くかかっている場合もあるようです。
image.png

GAS の記録

GAS の方では1回あたり大体10秒ちょっとかかっているようですね。エラーもほぼないようです。

image.png

image.png

スプレッドシートの記録

2ヶ月もデータを溜めると、スプレッドシートを開くのにも時間がかかるようになってしまいました(笑)
GAS で毎日 Google スプレッドシート上のグラフを画像にして Google ドライブに保存するようにもしており、またデータにアクセスしたい場合は Google Colab を使って Python で処理すれば、 Google スプレッドシートを直接開く必要がないので、端末のスペックに依存しなくて済むかと思いますが、これ以上データを蓄積したい場合は、 IoT 向けのストレージを使うべきでしょう。

image.png

試しに11月1日0時0分〜11月30日23時59分59秒までにスプレッドシートに記録された行数を数えてみると、42951行ありました。
60*24*30=43200 なので、249回だけ記録できなかったことがあるようですね。でも、 99.4% 以上の割合で記録できています!

また台風通過時の気圧のグラフです。肝心の台風の目通過時は、 obniz Cloud で12分おきに取得していたのですが、それでも台風通過の様子がよく分かりますね。
たまに値が飛んでいますが、自宅の環境センシングとしては十分です。
image.png

気になる請求金額は

image.png

ちゃんと無料枠に収まっていました!
ただし他にもプロジェクトがある場合や設定次第で課金される可能性も十分あるので、無料枠で使いたい方は十分お気をつけください!

最後に

Google Cloud Functions で obniz を1分おきに動かすことができました!
台風通過時の気圧の変化、季節や時間による温度や湿度の変化を可視化できて満足です。
エアコンをつけたときの温度と湿度の変化など、グラフを見て気付かされることもありますね。逆にグラフを見ればエアコンをいつつけたかも分かります。もっとセンサの種類を増やしたくなりました。
ただ、蓄積したデータへのアクセスが問題なので、より良いデータの蓄積方法も考えてみたいと思います。

Let's IoT!
Let's obniz!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
7
Help us understand the problem. What are the problem?