見出し画像

観葉植物のお世話をDX! その3~ Lambdaで水やりのタイミングをTwitterに通知する ~

はじめに

こんにちは。SHIFT DAAE 開発グループ所属のsakuraiです。
観葉植物のお世話のDXの第3回です。今回で最終回です!

今回の作業でついに水やりのタイミングの通知を受け取ることができます。
図で言うところの赤枠の部分になります。

まずは前回までの作業で蓄積した水分量データを分析して
どのタイミングで通知すればよいかを検討しましょう。

データの分析&通知タイミングの検討

7/17~7/22で計測したデータをグラフ化しました。
今回のセンサーとプログラムでは、水分量が0~1024の値で記録されています。1024に近いほど水分量は多く、0に近いほど乾燥しているということになります。(途中の急な変化はセンサーや鉢を移動したときの変化なのでスルーしてください。)

7/17の9時ごろの水やりから急激に数値が高くなり、そこから徐々に水分が減少していく様子が確認できました。

7/18~7/20までの間はほとんど減少しておらず、水やりから4日後の7/21から水分の減少量が大きくなっています。

もともとの水やりの目安として「春夏なら2~3日に1回」としていましたが、正しそうな周期ですね。ただ、大きく減り始めるのが4日後なので3~4日に1回でも良さそうです。
ということで今回は以下のルールで通知を行うこととしました。

  1. 毎朝9時に水分量を確認し、結果を投稿する。

  2. 水分量は8:30~9:00の平均値とする。

  3. 水分量が800以上の場合は水やりなし。

  4. 水分量が700~800の間は水やりを推奨する。

  5. 水分量が700以下の場合は、水やりをするよう通知する。

ではルールが決まったので、通知の仕組みを構築していきましょう。

通知システムの構築

まずは決めていなかったLINE or Twitterのどっちを利用する?の検討からです。今回はTwitterで通知する方式としました。その理由としては

  1. 水やり推奨期間は直接通知は行わず、タイムラインに表示のみする。

  2. 水やりが必要なタイミングから直接通知を行う。

という方式にしたかったからです。
推奨期間から毎日通知があると、必要なタイミングの通知を読み飛ばしてしまう危険性がありますからね。
では続けて構築していきましょう。

Lambda→Twitterへの連携については以下の記事が大変参考になりましたので、こちらを元にTwitterのAPI設定通知プログラムを作成を実施しました!ありがとうございます!
https://aws.amazon.com/jp/builders-flash/202201/aws-drill-twitter-bot-1

上記の構築が無事できたので、DynamoDBからの値の取得と通知ルールの実装を追加します。
最終的に以下のようになりました。

# lambda_function.py
# 参考元URL  https://aws.amazon.com/jp/builders-flash/202201/aws-drill-twitter-bot-1
import json
import boto3
import os
from boto3.dynamodb.conditions import Key
from datetime import datetime, timezone, timedelta
from requests_oauthlib import OAuth1Session

client = boto3.resource('dynamodb')

# APIキーやトークンをハードコーディングしていますが
# 参考元記事の通り、望ましくない実装であるため、実際に利用する場合は要改善となります。
consumer_key = '*Input Your API Key*'
client_secret = '*Input Your API Key Secret*'
access_token = '*Input Your Access Token*'
access_token_secret = '*Input Your Access Token Secret*'

oauth = OAuth1Session(consumer_key, client_secret, access_token, access_token_secret)

mention = '@通知先アカウント'

def lambda_handler(event, context):

    # 水分量をDynamoDBより取得
    moisture = getMoisture();

    # 水分量から書き込みメッセージを作成    
    text = 'おはようございます。今日の水分量は' + str(moisture) + 'です。\n'
    if moisture >= 800:
        text += '今日はお水大丈夫!\n' 
    
    elif 800 > moisture >= 700:
        text += 'そろそろお水ほしいかも?\n' 
    
    elif 700 >  moisture:
        text += 'みず。。。。。。\n' 
        text += mention 

    # つぶやく
    response = tweet(text);

    if response.status_code != 201:
        raise Exception(
            "[Error] {} {}".format(response.status_code, response.text)
        )
        
def tweet(text):
    payload = {'text': text}
    response = oauth.post(
        "https://api.twitter.com/2/tweets",
        json=payload,
    )
    return response
    
def getMoisture():
    JST = timezone(timedelta(hours=+9))
    dt = datetime(2022, 7, 21, hour=21, minute=0, second=0, tzinfo=JST)
    _now = int(dt.timestamp() * 1000)
    _30_min_ago = _now - (30 * 60 * 1000) 

    table = client.Table('pothos')
    response  = table.query(
        KeyConditionExpression=(
            Key('pkey').eq('sensor1')
            & Key('skey').between(_30_min_ago, _now)

        )
    )
        
    # 値が取得できない場合の処理は今回対象外とします。
    if(response['Count']==0):
        return -1;

    sum = 0;
    for item in response ['Items']:
        sum += item['payload']['moisture']

    return int(sum/response['Count'])

あとはこの関数を毎朝9時に実行すれば完了です!

できました

できました!想定通り、水分量によってメッセージが変わっています。
あとはこのアカウントをフォローしておき、「お水ほしいかも?」のタイミングで水やりを行えば良さそうです!
もし忘れても最終的にはポトスさんから通知が届くので、大丈夫そうですね。ポトスさんからレスキューツイートが届くまでに対応しましょう。

おわりに

無事システムが構築できたので、適切なタイミングで水やりができるように(多分)なりました!!良い!!
あとは秋冬になった場合、水分の減り方がどう変化するかを確認するのが楽しみですね。通知についてもこちらからメンションを飛ばすとグラフ画像を返すようにしたりと、いろいろできそうなのでしばらく運用してみて、より便利な案が思いつけば実施してみようと思います。

M5StickC Plusではその他の種類のセンサーの値の取得やそれ以外にもいろいろできそうなので、困ったことがあればまたM5StickC Plusで解決できないか考えてみたいと思います。

ということで今回はここまで。ありがとうございました~。


\もっと身近にもっとリアルに!DAAE公式Twitter/


執筆者プロフィール:sakurai
SHIFT DAAE部所属の開発エンジニアです。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/