11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

#ポトスにお水をあげなくちゃ:seedling:
私の部屋には、毎日つかれた心をいやしてくれる「ポトス」がいます。
今年の5月に100均で購入し、可愛がっていたら、
ぐんぐん育ってくれて…

とにかく、かわいいんです!

2、3日に1度、水やりをやっているのですが、
年に数回、地元へ帰省することがあり、
毎回7〜9日間ほど家をあけることがあります。

家を空けている期間は誰も水やりができないので、
このままでは、大切なポトスが苦しんでしまいます。

.

そんなわけで今回は、大切な観葉植物を毎日元気にするために、
RaspberryPiの工作を通して学んだ知識を活かして
水やりの自動化に挑戦していきました。

#完成イメージ
指定した時間に水やりをして、観葉植物の状態を撮影、
LINEに実行通知と画像を送信するプログラムを動かします。

#材料

#環境

  • PC:MacBook Pro2017(macOS Big Sur_Ver11.6.1)
  • エディタ:Atom(Ver1.58.0)
  • VNC Viewer(Ver6.20.529)
  • -raspbian
    • No LSB modules are available.
    • Distributor ID: Raspbian
    • Description: Raspbian GNU/Linux 10 (buster)
    • Release: 10
    • Codename: buster
  • Python:3.7.3

Atomを用いてリモートでRaspberryPiへアクセスする方法を過去に紹介しています。
作業性が良いので、ぜひ参考にしていただけたらと思います。
↓ ↓ ↓
RaspberryPi内のPythonファイルをAtomのリモート機能で編集したら最高だった

#手順
ラズパイのOSインストール、環境設定等に関する説明は割愛します。

なので、環境構築ができている前提で進めていきます。

##ポンプ制御
ポンプはUSB電源に接続すると、モータが駆動する仕様になっています。
RaspberryPiのUSBポートは常時通電しているので、
繋げたままだと無限給水してしまいます。

USBポートの電源をON、OFF制御できるようにしましょう。

.

まずは、USBを制御するためのhub-ctrlを導入します。

terminal
ターミナルに下記を入力

$ sudo apt-get install libusb-dev
$ wget http://www.gniibe.org/oitoite/ac-power-control-by-USB-hub/hub-ctrl.c
$ gcc -O2 hub-ctrl.c -o hub-ctrl-armhf-static -lusb -static
$ sudo cp hub-ctrl-armhf-static /usr/local/bin/hub-ctrl
watering.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import datetime
import os

# USB-ON
def USB_ON():
    print("USB-ON")
    os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 1")
    return

# USB-OFF
def USB_OFF():
    print("USB-OFF")
    os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 0")
    return

# 実行関数
def job():
    now_time = datetime.datetime.now()
    print("現在時刻 : ", now_time)

    # ON
    USB_ON()
    time.sleep(5)
   
    # OFF
    USB_OFF()

指定したUSBポートに対するON_OFF制御はできないみたいなので、
ON_OFFの切り替えは、全ポート行われます。

ちなみに、os.system("sudo hub-ctrl -b...の末尾の数字が、
1でON、0でOFFに切り替わります。

##Line通知+定期実行
過去に投稿した記事を参考に、Lineへの通知処理を実行します。
Lineのアクセストークンが必要になるので、
その取得方法等は下記のリンクをご参照ください。
↓ ↓ ↓
RaspberryPiを使って、インターホンを押すとLINEに通知が行く仕組みを1からつくってみた

また、下記の例だと20秒に一度の定期実行を行います。
定期実行はscheduleモジュールを使って実行できます。

watering.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import datetime
import os
import requests


# USB-ON
def USB_ON():
    print("USB-ON")
    os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 1")
    return

# USB-OFF
def USB_OFF():
    print("USB-OFF")
    os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 0")
    return

# Line通知
def Line_notify(message,sP_ID,s_ID):
    payload = {
    'message':message,
    'stickerPackageId': sP_ID,
    'stickerId': s_ID}
    headers = {'Authorization': 'Bearer ' + '発行したアクセストークンをここに書きます' }
    res = requests.post('https://notify-api.line.me/api/notify', data=payload, headers=headers)
    print(res)


# 実行関数
def job():
    now_time = datetime.datetime.now()
    print("現在時刻 : ", now_time)

    message = '\n\n水やりしたから、ヨシ!'
    sP_ID = 11538
    s_ID = 51626496

    # ON
    USB_ON()
    time.sleep(2)
    img = ShotPicture()
    Line_notify(message,sP_ID,s_ID)

    # OFF
    USB_OFF()
    os.remove(img)

# Test
schedule.every(20).seconds.do(job)

try:
    while True:
        schedule.run_pending()
        time.sleep(1)

except:
    USB_OFF()
    message = '\n\nなんかエラーが発生したっぽいけど、ヨシ!'
    sP_ID = 11538
    s_ID = 51626515
    Line_notify(message,sP_ID,s_ID)

実行すると、下記のようにLineへ通知が来ます。

##撮影・画像送信
WEBカメラでポトスを撮影して、Lineに送信します。

WEBカメラで撮影する前に、OpenCVの環境を構築を実施。
この環境構築なのですが、上手くできていないとプログラムを実行した際に、
下記のようにエラーが出力されてしまいます。

私は、このエラー解決にもっとも時間がかかったので、
備忘のため、記事を残します。

最終的には、下記の記事を参考に、
記事の最下部まで試してやっと環境構築ができました。
↓ ↓ ↓
【Raspberry Pi】Raspberry Pi Zero WにOpenCVの環境を構築する

撮影・画像送信を追加した水やりプログラムはこちら

watering.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import datetime
import os
import schedule
import requests
import cv2
from PIL import Image


# USB-ON
def USB_ON():
    print("USB-ON")
    os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 1")
    return

# USB-OFF
def USB_OFF():
    print("USB-OFF")
    os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 0")
    return

# Line通知
def Line_notify(message,sP_ID,s_ID,img):
    payload = {
    'message':message,
    'stickerPackageId': sP_ID,
    'stickerId': s_ID}
    files = {'imageFile':open(img, 'rb')}
    headers = {'Authorization': 'Bearer ' + '発行したアクセストークン' }
    res = requests.post('https://notify-api.line.me/api/notify', data=payload, headers=headers, files=files)
    print(res)

# カメラ撮影関数
def ShotPicture():
    Image_dir = "/home/pi/Desktop/"
    now = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
    file_name = now + '.jpg'
    cc = cv2.VideoCapture(0)
    ret, img = cc.read()
    cv2.imwrite(file_name, img)

    img = Image_dir + file_name
    cc.release()

    return(img)


# 実行関数
def job():
    now_time = datetime.datetime.now()
    print("現在時刻 : ", now_time)

    message = '\n\n水やりしたから、ヨシ!'
    sP_ID = 11538
    s_ID = 51626496

    # ON
    USB_ON()
    time.sleep(3)
    img = ShotPicture()
    Line_notify(message,sP_ID,s_ID,img)

    # OFF
    USB_OFF()
    os.remove(img)

# Test
schedule.every(20).seconds.do(job)
# Production
# schedule.every().day.at("07:00").do(job)

try:
    while True:
        schedule.run_pending()
        time.sleep(1)

except:
    USB_OFF()
    message = '\n\nなんかエラーが発生したっぽいけど、ヨシ!'
    sP_ID = None
    s_ID = None
    img = '/home/pi/Desktop/main.png'
    Line_notify(message,sP_ID,s_ID,img)

ShotPicture()で定義している部分で撮影の処理を行います。

このソースを実行させた結果がこちら。

テスト動作で水やりをさせていませんが、ヨシですね!

.

ちなみに、エラーが発生するとこうなります。

except節で定義している、デスクトップ上の画像を選択して送信させています。
また、水やり中にエラーが発生し、無限給水をしてしまわないように、
USB給電をOFFにする処理を実行させるようにします。

これでヨシですね。(たぶん)

##自動実行
過去にスケジューリングをするならsystemdがいいと聞いたので、
自動実行をするために、shellスクリプトとserviceファイル作成、
権限付与などの処理を行います。

こちらも、過去に投稿した記事がありますので
詳しくはこちらからどうぞ
↓ ↓ ↓
Raspberry Piでプログラムの自動起動をsystemdでやってみた

.

これで、自動水やりプログラムは完成です!

##たのしい工作

といっても、WEBカメラ、水中ポンプ、USBライトをRaspberryPiに差し込むだけ。

でおわる予定だったのですが、
USBライトはタッチセンサーのスイッチを押さないと点灯しない
仕様なので、ちょっとだけひと手間加わえます。

通電時に電源をONにしたいけど、どうしよう…

.

よし、考えるのはあとだ!!  分解!!

電子部品に関することは詳しくわからないのですが、
おそらく、タッチセンサーの信号をオペアンプで増幅させて、
抵抗の大きさが異なる回路に切り替えているのかなと思います
(間違っていたらごめんなさい…)

なんとなく、ICの部分を短絡させればいけるかなと思い、検証してみます。

.

すると画像の部分を短絡させることによって、
電源ONのときにLEDが点灯することに成功!

その辺に落ちてた配線をはんだ付けするだけで終了です。

もし、配線がない場合は、
緑色の配線(乾電池からの電源供給)を拝借しましょう。

小さい基盤ようのはんだごてを持っていないので、
配線を焦がしてしまったことは見逃してください。

##完成品
あとは、組み立て、いい感じに配線したら完成です。

#参考記事

#終わりに
まめコーヒーアドベントカレンダーの記事を書くネタを考える時期が、
たまたま帰省前だったので、こんな記事になってしましました。

この文章を書いている時に、コーヒーネタでもよかったなーと…

ポンプがあるなら、なんちゃってドリップマシンでもつくれたかもしれないですね。
来年のアドベントカレンダーのネタに取っておこうと思います。
(忘れているかもしれないけど)

.

最後まで見ていただきありがとうございました!!

11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?