Raspberry piとLINE Messaging APIでお野菜品質管理システムを作ってみた話。

IoT
この記事は約11分で読めます。
スポンサーリンク

昨年からシェア畑というサブスク型の貸し農園と、家庭菜園を初めて野菜を育てております

先日公開して記事にて、野菜を育てていることを書いたのですが、そちらの記事のおわりに記載していた「最適な野菜の育成環境を効率的に作り出す」という取り組みにしばらく従事しておりました。

一旦暫定版として構築完了したため、「お野菜品質管理システム」と題しましてどのようなものを作成したのかまとめてみようと思います。

家庭菜園で育てているカブを実験材料に、「お野菜品質管理システム」を作成

どのようなデータを取得すれば野菜の品質を向上させる最適な育成環境を作り出しやすくなるのか非常に迷ったのですが、以前購入していたRaspberry pi用のセンサーモジュールで取得できそうなデータの中から特に、「温度」と「土壌の水分量」を取得しそれを分かりやすい形式でLINEに送るようなシステムにしました。
温度を取得できるセンサーモジュール (BME280)では「湿度」と「気圧」も取得可能なため、ついでにそのデータも表示させるようにしています。
更に、野菜の成長具合や葉っぱの様子を確認できるように、Web Cameraで撮影した画像も送信するようにしてみました。
※ちなみに今家庭菜園で育てている野菜はカブです。。(^ ^)

お野菜品質管理システムの全体写真

「お野菜品質管理システム」の機能について

今回作成した「お野菜品質管理システム」ですが、大きく分けて以下の3つの機能を作成しております。
それぞれの機能について、LINE Messaging APIを使用してLINEメッセージとして気軽にLINEで情報を確認できるようにしてみました。

  1. お野菜写真撮影機能
  2. 気温・湿度・気圧測定機能
  3. 土壌水分量測定機能

本記事では一旦、「お野菜写真撮影機能」について解説できればと思います。

機能①「お野菜写真撮影機能」

まず前提条件として、システムを構築した環境情報を以下に記載します。

  • ハードウェア: Raspberry Pi 3 Model B
  • OS: Raspbian GNU/Linux 10 (buster)
  • Python: 3.7.3

本記事で解説する機能を実現させるために、「LINE Messaging API」と「Gyazo」という2つのサービスを使うため、もし同じ方法で実現させる場合はそれら2つのサービスへの登録が必要となります。そのため、以下のリンクを参考に事前準備をお願いいたします。

■LINE Messaging API

LINE Messaging APIの利用登録方法~LINEアカウント開発に必要なAPIキー発行申請 | AutoWorker〜Google Apps Script(GAS)とSikuliで始める業務改善入門
日本で最も普及しているメッセージアプリ「LINE」には「LINE Messaging API」が用意されています。 LINE公式アカウントの開発に必要なLINE Messaging...

■Gyazo

さらに、実際の回路図というか配線の図をfritzingというソフトを使用しなるべく見易いように図式化してみました。
本記事で説明する「お野菜写真撮影機能」を構築するにあたっては、Web Cameraを接続していただくだけでもOKです!
後続記事で解説予定の「気温・湿度・気圧測定機能」と「土壌水分量測定機能」の分も一気に配線してしまいたい場合は、図で示している配線を全て実施してしまっても良いかもしれません。

「お野菜品質管理システム」全体の配線図

Raspberry piのターミナルを開き、必要なPythonパッケージをインストールしましょう。

pip3 install requests opencv-python opencv-python-headless

以下のスクリーンショットを参考にして、LINE Messaging APIのアクセストークン・ユーザIDと、Gyazoのアクセストークンを控えます。

■LINE Messaging APIのチャネルアクセストークン

チャネルアクセストークン(長期)

■LINE Messaging APIのユーザID

あなたのユーザID

■Gyazoのアクセストークン

Your access token

次にWeb Cameraをはずした状態で以下のコマンドを入力し、デバイス情報を確認します。

$ ls /dev/video*
/dev/video10  /dev/video12  /dev/video14  /dev/video16
/dev/video1  /dev/video11  /dev/video13  /dev/video15

その後Web Cameraを接続後同じコマンドを入力し、もう一度デバイス情報を確認します。
以下のように表示された場合、「video0」が接続したデバイスということになりますので、その場合はこの後記載するPythonコード (camera_gyazo_line.py)9行目のcv2.VideoCapture(0)をそのまま使用できます。
※videoXの数字Xが異なる場合は、VideoCapture(X)に書き換える必要あり

$ ls /dev/video*
/dev/video0  /dev/video10  /dev/video12  /dev/video14  /dev/video16
/dev/video1  /dev/video11  /dev/video13  /dev/video15

あとは以下のコードを任意のディレクトリに作成し、python3で実行すれば一度Gyazoに画像がアップロードされ、そのURLをLNE Messaging APIに送信する形でLINEへ画像が送信されます。
画像ファイルを全て別名で保存してしまうとストレージを圧迫するため、同じファイル名で上書きするようにしています。画像格納先のパス (fname = ‘/home/pi/Works/camera/img/upload.jpg’)は適宜環境に合わせて書き換えてみてください。

■camera_gyazo_line.py

import requests
import cv2
import datetime
import os

# カメラで画像を取得し保存する
def capture_image():
    # カメラのオブジェクトを取得
    camera = cv2.VideoCapture(0)
    if not camera.isOpened():
        print("カメラを開けませんでした。")
        return None

    ret, img = camera.read()
    if not ret:
        print("画像の取得に失敗しました。")
        return None

    # 保存する画像ファイルパス
    fname = '/home/pi/Works/camera/img/upload.jpg'

    # 既存のファイルがあれば削除
    if os.path.exists(fname):
        os.remove(fname)

    # 画像を保存
    cv2.imwrite(fname, img)
    camera.release()
    return fname

# Gyazoへの画像アップロード処理
def upload_to_gyazo(image_path):
    ACCESS_TOKEN_G = "取得したGyazoのYour access token"
    URL = "https://upload.gyazo.com/api/upload"
    
    headers = {"Authorization": f"Bearer {ACCESS_TOKEN_G}"}
    
    with open(image_path, "rb") as f:
        files = {"imagedata": f.read()}
        
    description = "vegetables"
    response = requests.post(URL, headers=headers, files=files, data={"desc": description})

    if response.status_code == 200:
        print("Gyazoアップロード成功")
        response_data = response.json()
        return response_data.get("url")
    else:
        print(f"Gyazoアップロード失敗: {response.status_code}")
        return None

# LINEに画像を送信する
def send_line_image(gyazo_url):
    if not gyazo_url:
        print("Gyazo URLが取得できませんでした。")
        return

    ACCESS_TOKEN_L = '取得したLINE Messaging APIのチャネルアクセストークン(長期)'
    user_id = '取得したLINE Messaging APIのあなたのユーザID'

    data = {
        'to': user_id,
        'messages': [
            {
                "type": "image",
                "originalContentUrl": gyazo_url,
                "previewImageUrl": gyazo_url
            }
        ]
    }

    headers = {
        'Authorization': f'Bearer {ACCESS_TOKEN_L}',
        'Content-Type': 'application/json'
    }

    line_api_url = 'https://api.line.me/v2/bot/message/push'
    response = requests.post(line_api_url, headers=headers, json=data)

    if response.status_code == 200:
        print('LINEメッセージ送信成功')
    else:
        print(f'LINEメッセージ送信失敗: {response.status_code}, {response.text}')

# メイン処理
def main():
    # 画像を保存
    image_path = capture_image()
    if not image_path:
        return

    # Gyazoにアップロード
    gyazo_url = upload_to_gyazo(image_path)
    
    # LINEに送信
    send_line_image(gyazo_url)

if __name__ == "__main__":
    main()

■python3で実行

python3 camera_gyazo_line.py 
Gyazoアップロード成功
LINEメッセージ送信成功

実行後、上記のようにメッセージが表示されていれば成功です。
LINEの対象のトークルームに画像が送られてくるか確認してみましょう。

LINEに画像が送られてきた様子

もしも定期実行させる場合は、camera_gyazo_line.pyスクリプトを記載しておきましょう。
※以下の設定は、毎日12時3分に定期実行させる場合の記載方法です

crontab -l
# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command

# カブ画像配信
3 12 * * * python3 /home/pi/Works/camera/camera_gyazo_line.py

Crontabの使い方がわからない場合は、以下の参考ページをどうぞ!

初心者向けcronの使い方 - Qiita
unix系OSでは定期的にコマンドを実行するためにcronと呼ばれるデーモンプロセスがあります。決まった時間にログを集計してメールで送るなどの使い方ができて非常に便利です。ここではクーロンの設定方法…

おわりに

最後までお付き合いくださりありがとうございます。少し冗長になってしまったかもしれないですが、お役に立てましたら幸いです。追って「気温・湿度・気圧測定機能」「土壌水分量測定機能」の記事も作成予定となりますので、今しばらくお待ちください。。(^ ^)

コメント

タイトルとURLをコピーしました