土壌水分センサーの計測値をIFTTTを使ってSlack通知する


Raspberry Piと土壌水分センサーを使って、土の湿度を測り、Slack通知する仕組みを実装してみました。
これで観葉植物の水やりのタイミングに悩まないぞ!

参考サイト

以下のサイトを参考にさせて頂きました。ありがとうございます。

  1. https://dev.classmethod.jp/server-side/node-js-server-side/raspberry-pi-2-ad-convert-nodejs/
  2. http://mitolab.hatenablog.com/entry/2016/05/29/183244#f-22c9be72

使用機器

  • Raspberry Pi3 Model B
  • Grove 水分センサー モジュール Arduino
  • 10bit 8ch ADコンバータ MCP3008
  • ブレッドボード
  • ジャンパーコード ( オス - オス )
  • ジャンパーコード ( オス - メス )

とりあえず配線

慣れてないせいか、これが地味に一番悩んだ。。

上記の1のサイトを参考に配線したのですが、土壌湿度センサーの種類が違うのでセンサーから出てる線のつなぎ先が違った。。
自分が使用したのは Arduino用の Grove - Moisture Sensor でした。

センサーをよく見ると、SIG / VCC / GND の文字。

上記1のサイトの配線図の場合、
・緑色:出力(SIG)
・赤色:電源(VCC)
・黒色:グランド(GND)

なので、照らし合わせながら、無事、配線完了。

計測プログラム

これも、上記の1つ目の参考サイトのコードのままで動作しました。
プログラムはnodeで書いています。

計測値

2番目の参考サイトによると以下のレンジで土の状態を判定できそうです。

出力値   状態
0~1292  乾いた土
1292~3017   湿った土
3017~4095   水の中

IFTTTで連携する

今回、計測した値を連携するのに IFTTT(イフト)を使用しました。
IFTTTとは、「if this then that」(これをしたらあれをする)という、何かをトリガーに色々なアクションを実行できるサービスです。

このトリガーは、決められたサービスだけではなく、web hookによりRaspberry Piからも連携が可能です。

今回、計測値をそのまま連携し、IFTTTで何を行うかを全て判断するようにしました。

Raspberry Piの計測プログラム

index.js
/**
 * Raspberry Pi 2 (Model B) read SPI data from MCP3208 chip, 8 possible adc's.
 */

var raspi    = require('raspi');
var gpio     = require('raspi-gpio');
var request  = require('request');

const HIGH   = gpio.HIGH;
const LOW    = gpio.LOW;
const Input  = gpio.DigitalInput;
const Output = gpio.DigitalOutput;

var initHandler = function() {

    var d_in  = new Output('GPIO10'); //SPI_MOSI
    var d_out = new Input('GPIO9');   //SPI_MISO
    var clk   = new Output('GPIO11'); //SPI_CSLK
    var cs    = new Output({ 'pin' : 'GPIO8', 'pullResistor' : gpio.PULL_UP });  //SPI_CE0

    var clock = function(count) {
        for(var i = 0; i < count; i++) {
            clk.write(HIGH);
            clk.write(LOW);
        }
    };

    var readValue = function() {
        cs.write(LOW); //start

        var i;
        var ch  = 0; // 0 ch. (0~7)
        var cmd = ( ch | 0x18 ) << 3;
        for(i = 0; i < 5; i++) {
            d_in.write( ( cmd & 0x80 ) ? HIGH : LOW );
            cmd <<= 1;
            clock(1);
        }

        var result = 0;
        for(i = 0; i < 13; i++) { // one null bit and 12 ADC bits.
            result <<= 1;
            clock(1);
            if(d_out.read()) { // === 1
                result |= 0x1;
            }
        }

        cs.write(HIGH); //end

        //console.log('result : ', result);
        // IFTTT連携
        var options = {
            uri: "<IFTTTのhook URL>",
            headers: {
                "Content-type": "application/json",
            },
            json: {
                "value1": String(result)
            }
        };
        request.post(options, function(error, response, body) {
            process.exit();
        });
    };

    readValue(); 
};

raspi.init(initHandler);

IFTTT Platform にて、以下のようなPrivate Applet を作成しました。

Filterと呼ばれる機能を利用することにより、計測値から状態を判断して通知メッセージに変換するようにしました。

結果

ついでに計測値をGoogle Spread Sheetにも連携してみた

IFTTTからGoogle Spread Sheetへの連携もできるため、同じイベントをhookして書き込んでみました。

センサーを水に濡らしたティッシュに包んで放置してたんですが、乾燥するにつれて、ちゃんと値が下がっていってるのが確認できます。

まとめ

はじめはIFTTTの設定方法が良く分からず手間取りましたが、ほとんどコードを書くことなく、Raspberry PiとSlackを簡単に連携することができました。
これからDIYが捗りそうです。