🐢

【RaspberryPi/Slack】亀の自動餌やり機を遠隔操作する

2023/06/25に公開

はじめに

私は家でミシシッピニオイガメを飼っております。丸っこくてコンパクトな可愛い亀です。

ときどき用事で家を離れるときがあり、その際に餌やりをどうしようかという問題が出てきます。それを部分的に解決してくれるのが、こちらの自動餌やり機です。
Gex デジタルフードクロック FC-002D

しかし、実際に使用してみるといくつか問題が出てきました。

  1. 餌の量の細かな調節ができず、一度にたくさんの量が出てしまうと、食べ残してしまう。1回の量を少なくして何度も餌を投下できればいいが、タイマーは1日8回(4時刻×各2回)までしか設定できない。(量調節問題
  2. 亀ちゃんの食べたいタイミングで餌が投下されないと、餌に気づかずに食べ残してしまう。(タイミング問題

自動餌やり機にはマニュアルボタンがついており、そのボタンを押すことで任意のタイミングで餌を投下できるようになっています。そこで、このボタンを遠隔地からでも押せるようにすることで、タイマーに依存せずに少量を何度も投下すれば、量調節問題は解決です。

さらに、TP-LinkのTapo C210でリアルタイム監視をできるようにしているので、亀ちゃんが餌を食べたそうにしているかは、遠隔で確認できます。
そのタイミングで集中的に餌を投下してあげれば、タイミング問題も解決です。

ということで、遠隔からマニュアルボタンが押せるように改造を施すことにしました。

どう実現するか

  1. 遠隔地からRaspberryPiに指示を出す。
  2. 指示を受け取ったタイミングで、GPIO経由でマニュアルボタンを押下する。

1. 遠隔地からRaspberryPiに指示を出す

RaspberryPiにローカルネットワーク外から指示を出す方法を調べていくと、よくヒットしたのがWebSocketを使うものと、 WebIOPiを使うものでした。Webブラウザ経由で自由にRaspberryPiのGPIOなどに指示を出せるということでした。

しかし、どちらも外部ネットワークから接続するためには、プライベートIPアドレスを固定し、グローバルIPのポートと紐付けて、そのポート経由でWebブラウザから指示を出すということで、ややセキュリティ上の不安があったり、元に戻すのがめんどうだったりと、あまり気が進まない面がありました。WebIOPiは2015年から更新されていないというのも懸念点でした。

そんな中で、Slackの「Socket Mode」により、Slackの投稿またはショートカットを使ってRaspberryPiに指示を出すという方法を紹介してくださっている素敵な記事を見つけました。これなら安心かつスマートにできそうだということで、この方法を採用させていただきました。

具体的なプロセスについては、上記の素敵な記事にもある通り、以下のQiita記事を参考にさせていただきました。
https://qiita.com/seratch/items/1a460c08c3e245b56441

2. 指示を受け取ったタイミングで、GPIO経由でマニュアルボタンを押下する

これを最も手軽に実現する方法としては、サーボモーターを使ってボタンを物理的に押す、ということがあります。
サーボモーターを動かすのには、こちらの記事を参考にさせていただきました。

上記1、2をまとめたPythonプログラムがこちら

turtle_feeder.py
import logging
import os
from slack_sdk import WebClient
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
import pigpio
import time

logging.basicConfig(level=logging.DEBUG)

SLACK_APP_TOKEN="xapp-で始まるトークン"
SLACK_BOT_TOKEN="xoxb-で始まるトークン"
Turtle_ch="SlackチャンネルのURLの最後「/」以降の文字列"

app = App(token=SLACK_BOT_TOKEN)
client = WebClient(SLACK_BOT_TOKEN)

SERVO_PIN = 18
pi = pigpio.pi()

# 投稿に「エサ」の文字が含まれていたら実行
@app.message("エサ")
def handle_messge_evnts(message, say):
	servo_action()
	say(f" <@{message['user']}> 亀ちゃんにごはんをあげました!")	

# Socket Mode内に作成したグローバルショートカットを起動したら実行
def handle_shortcut(ack, body: dict, client: WebClient, say):
	ack()
	servo_action()
	say(channel=Turtle_ch, text="亀ちゃんにごはんをあげました!!")

# サーボモーターを作動させる関数
def servo_action():
	pi.set_servo_pulsewidth(SERVO_PIN, 1500)
	time.sleep(0.5)
	pi.set_servo_pulsewidth(SERVO_PIN, 500)
	time.sleep(0.5)
	pi.set_servo_pulsewidth(SERVO_PIN, 1500)

	
if __name__ == "__main__":
	handler = SocketModeHandler(app,SLACK_APP_TOKEN)
	handler.start()

注意点として、pigpioを使用する際には、

$ sudo pigpiod

を実行しておく必要があるため、自分は以下のシェルスクリプトを作成しました。

start_turtle_feeder.sh
sudo pigpiod
python turtle_feeder.py

これを実行するには、ターミナルで以下を入力します

$ bash start_turtle_feeder.sh

実際に動く様子

いい感じの角度にサーボホーンを固定するのに、地味に手こずりました。
実際に動く様子

設置した様子

設置した様子1
設置した様子2
設置した様子3
RaspberryPi Zeroを使用

追記予定

現状スイッチを物理的に押していますが、以下の記事ではトランジスタを使って電子的にスイッチを押すことを実現されていたので、電子的なスイッチ押下に近々変更予定です。(なぜかサーボモーターが停止時にも微小な音を発し続けているのがやや心配なのもあり)
https://elchika.com/article/03e63fbe-f997-4169-bac0-abc3d0ef5bd8/

おわりに

まさかSlackのAPIを使用することで、こんなにスマートにIoTが作成できてしまうというのが衝撃でした。これでいつでも好きなタイミングで、亀ちゃんに餌をあげることができるので安心です!

参考

https://denor.jp/raspberry-piでソフトウェア的なスイッチカチカチ押す方
https://craft-gogo.com/raspberry-pi-webiopi/
https://elchika.com/article/612f4e01-33ee-4292-87b4-bd6bbf84c2d5/#h_自宅外から自宅内への通信の課題
https://sozorablog.com/servo/

Discussion