ITmedia NEWS > STUDIO >
連載
» 2021年07月22日 07時00分 公開

庭の水やりで身近なIoTを体験、自動水やりシステムの構築 〜給水をLINEで通知〜名刺サイズの超小型PC「ラズパイ」で遊ぶ(第43回)

ラズパイを使って土中の水分量をもとにした水やりシステム。今回は自動で給水が行われた際に、LINEで通知を受け取れるようにします。

[岩泉茂,ITmedia]

 クレマチスに水をやるシステムの解説は第42回で終わりにするつもりだったのですが、実際に運用していくと改良すべき部分が出てきました。まずは給水したらLINEで通知を受け取れるようにするシステムです。

 これまではLCDやLEDによる表示で地中の水分状態を分かるようにしてきたのですが、これは「もうすぐ給水される」ということは分かるが「いつ給水したか」は分からないのが欠点でした。これを解消するために給水をLINEで知らせる仕組みを作ることにします。

 通知にLINEを使うシステムは基本的に第10回で紹介した通りです。まずは「Line Notify」のページで自身のLINEアカウントでログインし、LINEのトークンを発行します。発行されたトークンは二度と表示されないので、発行された画面でコピーしてテキストを保存しておきます。

LINE Notify LINE Notifyのページにログインする
LINE Notify 「トークンを発行する」をクリック
LINE Notify 送信する相手を選択する
LINE Notify トークンをコピーする
LINE Notify サービスを作成できた
LINE Notify 給水するとLINEにメッセージが届く

 次に、発行されたトークンをプログラムの中に組み込みます。ここでは「Dry」となったときに給水する仕組みなので、その箇所へ追記すればOKです。

(前略)
        if (hum > wet_l3):
            command(LCD_2ndline)
            print("Dry")
            writeLCD("Dry     ")
            led1.on()
            url = "https://notify-api.line.me/api/notify" # 追加
            access_token = '*****************************************'# トークンを記述
            headers = {'Authorization': 'Bearer ' + access_token}# 追加
            message = '水やりを開始します' # 追加
            payload = {'message': message}# 追加
            r = requests.post(url, headers=headers, params=payload,)# 追加
            motor.forward()
            time.sleep(10)
            motor.stop()
            time.sleep(1)
(後略)

 また、以前は地中の水分状態を3段階で検知していましたが、今回から4段階で検知するようにしました。これに合わせてLEDを3色用意し、水分状態に応じて青の点滅、黄色の点滅、赤の警告と光らせるようにしました。さらにいつ測定された状態を表示しているのかコンソール画面で分かるように時刻と合わせて表示させます。

 これまでより短い間隔で地中の水分状態を判定できるように、プログラムをループするタイミングも1秒に変更しました。これらの変更箇所を含めたプログラムは以下のようになります。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import subprocess
import requests
import smbus
import datetime
from gpiozero import MCP3002
from gpiozero import LED
from gpiozero import Motor
Vref = 3.3 # 基準となるラズパイの電圧
led1 = LED(20) # LEDをGPIO 20(38番ピン)に接続
led2 = LED(21) # LEDをGPIO 21(40番ピン)に接続
led3 = LED(25) # LEDをGPIO 25(22番ピン)に接続
motor = Motor(forward=18, backward=23) # モーターをつないだGPIO
i2c = smbus.SMBus(1)
addr = 0x3e # AQM0802のアドレス
# AQM0802の初期化
def_command = 0x00
def_data = 0x40
def_clear = 0x01
display_On = 0x0f
LCD_2ndline = 0x40 + 0x80
# 値の最大値と最小値
dry = 260
water = 130
interval = (dry - water) / 4
wet_l1 = water + interval
wet_l2 = wet_l1 + interval
wet_l3 = wet_l2 + interval
# AQM0802の関数
def command( code ):
        i2c.write_byte_data(addr, def_command, code)
  
def writeLCD( message ):
        mojilist=[]
        for moji in message:
            mojilist.append(ord(moji)) 
        i2c.write_i2c_block_data(addr, def_data, mojilist)
 
def init_lcd ():
        command(0x38)
        command(0x39)
        command(0x14)
        command(0x73)
        command(0x56)
        command(0x6c)
        command(0x38)
        command(def_clear)
        command(display_On)
init_lcd()
time.sleep(0.2)
writeLCD("Env is:")
try:
    while True:
        pot = MCP3002(channel=0)
        hum = round(pot.value * Vref * 100,1)
        d = datetime.datetime.now()
        print(d.strftime('%H:%M:%S'))
        if (hum > wet_l3):
            command(LCD_2ndline)
            print("Dry")
            writeLCD("Dry     ")
            led1.on()
            url = "https://notify-api.line.me/api/notify"
            access_token = 'kaZDeBjb1G3tKpxti4Lgm3NsyFyKYIon7uIiQ9yMnyG'
            headers = {'Authorization': 'Bearer ' + access_token}
            message = '水やりを開始します'
            payload = {'message': message}
            r = requests.post(url, headers=headers, params=payload,)
            motor.forward()
            time.sleep(10)
            motor.stop()
            time.sleep(1)
            
        elif (hum < wet_l3 and hum > wet_l2):
            command(LCD_2ndline)
            print("Wet lv.2")
            writeLCD("Wet lv.2")
            led2.on()
            time.sleep(0.2)
            led2.off()
            time.sleep(0.2)
            led2.on()
            time.sleep(0.2)
            led2.off()
            time.sleep(0.2)
            led2.on()
            time.sleep(0.2)
            led2.off()
        elif (hum < wet_l2 and hum > wet_l1):
            command(LCD_2ndline)
            print("Wet lv.1")
            writeLCD("Wet lv.1")
            led3.on()
            time.sleep(2)
            led3.off()
        elif (hum < wet_l1):
            command(LCD_2ndline)
            motor.stop()
            print("very Wet")
            writeLCD("very Wet")
            led.off()
        time.sleep(1)
except: KeyboardInterrupt
command(def_clear)
subprocess.call('clear')
LINE Notify 最終的に組み上げたシステム
LINE Notify 実際の水やりはこのような状態に落ち着いた。今年のクレマチスは大きな花がたくさん咲いた

Copyright © ITmedia, Inc. All Rights Reserved.