夏休みの子どもの自由研究に最適! 植物からメールをもらおうArduinoで始めるWeb技術者のためのIoT入門(3)(2/3 ページ)

» 2014年08月01日 18時00分 公開
[岩永義弘株式会社インターネットイニシアティブ]

「水やりが必要になったか?」を判断させる

 通知のロジックを設計するとき、最初に思い浮かぶのは、「土壌湿度が指定値より低くなったらメールする」という単純なアプローチだと思います。しかし、これには問題があって、乾燥状態になってから水やりをするまでの間は、センサー値を取得するたびにメールが届くことになり、同じメッセージでメールボックスが埋め尽くされてしまいます。

 従って、変化があったときだけメールを送るようにする必要があります。要件をまとめると次のようになります。

  • 知りたいのは、「水やりが必要になったこと」と「水やりが行われて、正常な状態に戻ったこと」の二つ
  • 通知は、状態が変化したときに1回だけ

 以上を実現するために、状態を管理する機構(ステートマシーン)を実装します。各状態と遷移条件は次の図のようにしてみます。

状態遷移図

 注目してほしいのは、「乾燥」から「正常」へ遷移する条件で、閾(しきい)値にマージンを加えている点です。これは、センサー値の揺らぎ対策のためで、図を交えて詳しく解説します。

 まず、土壌湿度を測定するに当たって、次のような前提があります。

  • センサーには誤差があり、誤差の範囲で値が揺らぐ
  • 土壌の乾燥は緩やかに進行し、水やりをすると即座に湿度が上昇する

 「乾燥した」と見なすセンサーの値を上図の閾値とします。前提で述べた通り、乾燥は非常にゆっくりと進行するため、センサーの誤差も相まって、閾値付近で値が揺らぐことで何度も状態が入れ替わる状況が発生します。なので、単純な状態の切り替わりだけを通知の条件にしてしまうと、大量のメールが届いてしまいます。

 この揺らぎに起因する状態遷移を防ぐため、「乾燥」→「正常」の遷移条件のみに、揺らぎ幅より十分大きな値をマージンとして加えています。つまり、「一度乾燥状態になると、水やりによって湿度が大きく上昇しない限り、正常状態に遷移しない」という制約を課しています。

 これをコードにした例が次になります。Node.jsモジュールとして外出しします。

function StateMachine(option){
    option = option || {};
    this.state           = 'OK';
    this.threshold       = option.threshold       || 100;
    this.thresholdMargin = option.thresholdMargin || 50;
}
 
StateMachine.prototype.determineTransition = function(newData){
    if ( this.state === 'OK' && !this._isSoilHumidityOK(newData) ) {
        // OK -> NG
        this.updateState(newData);
        return 'NG';
    } else if ( this.state === 'NG' && this._isSoilHumidityOK(newData) ) {
        // NG -> OK
        this.updateState(newData);
        return 'OK';
    }
    // OK -> OK or NG -> NG
    return 'no transition';
};
 
StateMachine.prototype._isSoilHumidityOK = function(newData){
    // add margin only on [NG -> OK] transition
    // to suppress mass notification by data fluctuation.
    if (this.state === 'NG') {
        return (newData > this.threshold + this.thresholdMargin);
    }
    return (newData > this.threshold);
};
 
StateMachine.prototype.updateState = function(newData) {
    this.state = (this._isSoilHumidityOK(newData) === true) ? 'OK' : 'NG';
};
 
module.exports = StateMachine;
stateMachine.js

 determineTransitionメソッドの引数にセンサーの値を渡すと、どの状態に遷移したのかを返しつつ、状態を更新します。NGからOKへの遷移条件にマージンを加えているのが26行目です。

これぞInternet of Things! Arduinoとメールサーバーを連携させよう

 次はいよいよインターネットの先にあるシステムと連携させる部分です。

メールAPIサービスに登録

 メール通知をするために、「MailGun」というサービスを利用します。これは、Web APIで手軽にメールを送信できるサービスです。月間1万通は無料で送信可能です。

 登録するには、まず下記URLでサインアップ手続きをし、ログインしてください。

 次に、下記URLで「API Key」「Mailgun Subdomains」を確認してくだい。後のプログラムで利用します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。