1
Help us understand the problem. What are the problem?

posted at

updated at

初心者がRaspberry Pi4 Bを購入後してSlackbotでカメラ撮影するまで

0. はじめに

大学院の学生企画でラズパイを触る機会があり、結構面白いことがやれると判明。大学内で使えるslackbotを構築したく、ラズパイを購入しました。やりたかったことは、ラズパイのカメラモジュールを使って、slack上で写真撮影してくれるbotづくり。実験室の機器や生体試料をたまに観察したいときに使う予定です。

成果物はこんな感じ。特定のメッセージに反応して、撮影→slackへの投稿まで全部やってくれる。

名称未設定 1.png

正直何番煎じだよっていう感じなので、該当の記事はありました。しかし多くの記事が古く、様々な方法が混在しているので最新のやり方を収集するのに苦労しました。備忘録として、そして何より「これから似たようなことやるよ!」っていう人に対して少しでも役に立たせられるよう、記事にします。

購入したラズパイはRaspberry Pi4 B 4GBカメラモジュールも購入。
他にもモニター、マウス、キーボード、microSDカード、microHDMIケーブルが必要。ケーブル以外は基本あると思います。

余談ですが、大学生協にラズパイの公式ケースが売られていました...... 今まで気にも留めてなかったので、これには正直びっくり。

1. OSの書き込み

楽勝。NOOBSとかあるみたいですけどRaspberry Pi Imagerが今スタンダードらしい。

  1. ラズパイ用のmicroSDカードとOS書き込み用のPCを用意する。
  2. Raspberry Pi OSのホームページからRaspberry Pi Imagerをインストール
  3. Raspberry Pi Imagerを起動したらmicroSDカードにOSを焼く。
    デフォルトは32bit版だがなんとなーく64bit版を入れてしまった。後悔することに。 普通に32bit版で良い。
  4. microSDをラズパイに挿して起動。

2. ネットワーク設定

地味にハマリポイントがあるので注意。ただし設定自体は楽でした。GUIベースでやってもいいですが、ステルスssidだとCLIベースで設定しないといけません。
ここでは大学の無線LANをありがたく使わせていただくことにしました。この無線LANはIEEE802.1X認証の必要なネットワークで、ブラウザ認証が要らない接続方法。Winやmacは比較的容易に接続可能でしたが、Linux(というかラズパイ?)だとかなり面倒でした。

  1. LX Terminal を起動 (Alt+Ctrl+T)

  2. sudo iwlist wlan0 scan コマンドを打ち、ネットワークを探す。

  3. 使用したいネットワークを見つけ、ESSIDを控えておく。

  4. sudo nano /etc/wpa_supplicant/wpa_supplicant.conf コマンドで.confファイルを編集。

  5. 下記を追加 (passwordはハッシュ化しておいたほうが良いが、ここでは割愛。)
    記入したらCtrl + O -> Ctrl + X

    /etc/wpa_supplicant/wpa_supplicant.conf
    network={
         ssid="控えておいたESSID"
         scan_ssid=1
         key_mgmt=WPA-EAP
         pairwise=CCMP
         auth_alg=OPEN
         eap=PEAP
         identity="IEEE802.1X認証に必要なID"
         password="IEEE802.1X認証に必要なpassword"
         phase1="peaplabel=0"
         phase2="auth=MSCHAPV2"
         priority=1
    }
    

Raspberry pi 3まではこれで良かったらしいのですが、4からはネットワークの変更によりもうひと手間必要。前述したハマリポイント
sudo nano /etc/dhcpcd.confコマンドを入力し、下記を追加。sudo rebootで再起動。接続されているかを確認。

/etc/dhcpcd.conf
interface wlan0
env ifwireless=1
env wpa_supplicant_driver=wext,nl80211

参考記事

ラズパイを大学の無線LANに接続する
Raspberry Pi 4 セットアップまとめ

3. ssh, vnc接続設定

ずっと一つのところに置いておく運用なので、いちいちmicroHDMIケーブルを挿したくない。そこで、リモート接続を可能にするべくssh(CLIによる接続)とvnc(GUIによる接続)も有効化しておきます。これで同じLAN環境にいればリモートでファイルの編集が可能になります。設定自体は超簡単、さすがLinux。

  1. sudo mkdir /boot/sshコマンドを実行
  2. 「設定」→「Raspberry Piの設定」からSSH、VNCを有効にする。
  3. ifconfigコマンドを叩き、ipアドレスを控える。
  4. 同一のLAN環境にいるPCからラズパイにアクセスする。
    sshであればssh ラズパイのユーザー名(デフォルトはpi)@控えておいたipアドレスを接続元のPCで入力し、パスワードを打てばok。vncの場合vnc viewerを接続元のPCにインストールし、控えておいたipアドレスで接続すればいい。もし、vnc viewer上で「Cannot currently show the desktop」と表示されたら、ラズパイ上でsudo nano /boot/config.txtコマンドを打ち、「#hdmi_force_hotplug=1」を「hdmi_force_hotplug=1」に修正すれば見られるはずです。

参考記事

Raspberry PiのSSH設定方法
【ラズパイ4】「Cannot currently show the desktop」エラーでデスクトップ画面が表示されない場合の対策

4. 日本語入力+VScode インストール

ラズパイはデフォルトで日本語入力に対応していないので日本語入力エンジンの Mozc をインストールする。中身は「Google日本語入力」のオープンソース版なので、変換精度はなかなか優秀。
ついでにVS Codeも入れておく。

  1. LX Terminal を起動 (Alt+Ctrl+T)

  2. 下記を入力しEnter。再起動される。

    sudo apt update
    sudo apt full-upgrade
    sudo apt install fcitx-mozc -y
    sudo apt install code -y
    sudo reboot
    
  3. winキーを押す or 左上のラズパイマークを押す。

  4. 設定->fcitx設定と入り、入力メソッドの設定ウィンドウを出す。

  5. 全体の設定タブを開き、入力メソッドのオンオフからホットキーの設定を行う。(「空」ボタンを押した後、全角半角キーを打てば良い。「zennkakuhankaku」と入力されていれば成功)

参考記事

Raspberry Piに日本語で入力できる設定方法(fcitx-mozc)

5. Slackbotの構築

様々な方法があるようで面食らいました。しかしSlack-boltが公式で提供されているのでそれを活用します。一回設定できれば後は関数を追記していくだけなのでかなり楽。

  1. slack_botを常駐させたいworkspace上でアプリを作成する。とりあえずSlack ソケットモードの最も簡単な始め方Slack API を使用してメッセージを投稿するの記事に従い、諸々の設定を行った。ソケットモードを有効にする必要があったかは正直わからない。注意すべき点はFeatures > OAuth & Permissionsでfile:writeを追加しておく点。

  2. pip を使っていくつかのモジュールをインストール。pip install opencv-python slack_boltラズパイのカメラモジュールを使用する予定だったので'''PiCamera'''を一度インストール。が、64bit版のラズパイOSだとOSエラーが出て使用できない!。(た後悔ポイント) 仕方がないのでopencvで代用。

  3. 適当なディレクトリにpythonのスクリプトを書く。書き方としては@app.message("")でトリガーとなるメッセージを指定し、その直後に関数定義をすればいいらしい。スクリプト自体は簡単に書けました。さすがPython。

    slack_bot.py
    import logging
    import os
    from slack_sdk import WebClient
    from slack_bolt import App
    from slack_bolt.adapter.socket_mode import SocketModeHandler
    from slack_sdk.errors import SlackApiError
    import cv2
    
    BOT_TOKEN = "BOT_TOKEN"
    APP_TOKEN = "APP_TOKEN"
    
    logger = logging.getLogger(__name__)
    
    @app.message(r"写真撮って|:camera:")
    def take_photo(message, say):
        say(f"<@{message['user']}> さん、撮影を開始します。")
        cap = cv2.VideoCapture(0) #0 or -1
        if cap.isOpened():
            ret, img = cap.read()
        if ret:
            cv2.imwrite('temp.jpg', img)
            cv2.destroyAllWindows()
        say(f"撮影完了です!")
        try:
            result = app.client.files_upload(
            channels="常駐させたいチャンネル名",
            initial_comment="撮影結果です :grin:",
            file="temp.jpg"
            )
            # Log the result
            logger.info(result)
        except SlackApiError as e:
            logger.error("Error uploading file: {}".format(e))
        os.remove("temp.jpg")
    
  4. 走らせてみる。成果物と同じように、メッセージに反応して写真を撮ってくれれば成功。

参考記事

Slack ソケットモードの最も簡単な始め方
files.upload (API公式ホームページ)
Slack Python SDK でチャンネルにファイルをアップロードしよう

6. python fileの自動起動

いちいちpythonファイルを起動するのは面倒なので自動起動させる。様々な方法があるがsystemdを用いた方法が一番robust。結構ハマった。

  1. LX Terminal を起動 (Alt+Ctrl+T)

  2. cd /etc/systemd/system/と入力

  3. sudo nano 任意のサービス名.serviceと入力。サービス名は英語でわかりやすいものにする。

  4. 下記内容を入力し、保存

    /etc/systemd/system/任意のサービス名.service
    [Unit]
    Description= launch python file # サービスの内容説明
    After=network.target # ハマリポイント。Slack_botの際はこれが必須。
    
    [Service]
    ExecStart=/usr/bin/python3 /path/to/your/python/script.py
    Restart = always # 動作がおかしくなるようなら noに変える。
    [Install]
    WantedBy=default.target
    
  5. sudo systemctl daemon-reloadでsystemdを再読み込み

  6. sudo systemctl start 作成したサービス名でサービスを起動

  7. sudo systemctl status サービス名でRunningの表示があるかを確認。ない場合は、python fileにバグが有るかサービス内の記述に間違いがないか(指定したスクリプトのpathなど)を確認

  8. sudo systemctl enable サービス名で自動起動をonにする

  9. sudo reboot。再起動後にsudo systemctl status サービス名でRunningの表示があるかを確認。

注意点

サービスで指定されているpythonファイルを修正した場合、修正後に一度sudo systemctl stop 作成したサービス名を行いサービスを停止させた後に5. 以降の手順をもう一度行うことを推奨。

参考記事

systemctl daemon-reload って何
半年前の自分に教えたい systemd のハマりどころ

7. 最後に

以上のステップを踏めば、電源を入れるだけで指定のpythonファイルが走りますし、外部からssh or vnc接続できるのでpythonの編集や電源のオンオフ、再起動もできます。実質的に無線LANと電源が届く限り、カメラ撮影が可能になるので、研究にかなり使えるポテンシャルがありそう。あとはこのシステムを属人化させないためにも、ちゃんと後輩に引き継がさねば......。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
1
Help us understand the problem. What are the problem?