背景
「くるみちゃん」というシルバーのトイプードルを飼っています。
夫婦共働きなので、毎日長時間のお留守番を頑張ってくれています。
昨年、冬に部屋が寒すぎてお腹を壊してしまったくるみちゃん・・・
家に帰ったら惨状が・・・
慌てて病院に連れて行きましたが、その時は原因がわからず一週間惨状が続きました。
その後、留守中のくるみちゃんの様子が心配で、
見守りシステムを作ることにしました!!
解決したい課題
- 外出先からお留守番の様子が見えない
- 部屋の温度が夕方から急激に寒くなる
システム要件
我が家は、夫婦Slackを導入しているので、見守りもSlackで行うことにしました。
- お留守番の様子を、Slackから任意のタイミングで写真を撮ることができる
- 定期的に温度を取得しSlackにつぶやく
- Slackでエアコンのオン/オフができる
準備したもの
電子工作的なもの
- Raspberry pi3
- カメラモジュール(純正)
- 温湿度センサー(DHT22)
- 光センサ付赤外線LEDリングライト 850nm OSFKS5CS
- 赤外線受信モジュール(KY-022)
- 5mm赤外線LED3個
- 光センサー(GY-30)
システム的なもの
- Slack
開発環境
- MacOSX
- センサーの操作:Python
- Slack Bot:Hubot+CoffeeScript
配線
RaspberryPi構築
RaspberryPiのセットアップ
Raspberrypiが未セットアップの方は、こちらがとても丁寧に解説されていますので参考になさってください!
我が家はセットアップ済みのRasperryPiが何個か転がっているので、そのうちの一つを使いました。
RaspberryPiからエアコン操作
赤外線リモコンを作る
Slackからエアコンをつけられるように、まずは赤外線リモコンを作ります。
配線〜スクリプトまで、基本的には、この本で全て作れます!!めちゃくちゃお世話になりました。
赤外線送信コマンド
このコマンドを、後にSlackから操作します。
目的 | コマンド |
---|---|
暖房オン | irsend SEND_ONCE aircon warm24 |
冷房オン | irsend SEND_ONCE aircon cool27 |
エアコンオフ | irsend SEND_ONCE aircon off |
つまずいたところ
- エアコンの種類によって、赤外線学習がうまくいかなかった
我が家のエアコンは日立のしろくまくんを使っているのですが、
この本に載っているirrecordを使った赤外線記憶の方法ではうまくいかなかったため、
下記ホームページを参考にさせて頂きました。
- 赤外線の指向性?
赤外線送信モジュール一つだと、エアコンの受光するところに近づけて(2mくらい?)ピンポイントで発射しないと、エアコンが反応してくれなかった。
そのため、赤外線LEDを3つ繋いで、強化しました。
指向性の問題については、拡散キャップを使うことで解決できるかと思いましたが、赤外線が弱くなってしまうため、使うことは見送りました。
RaspberryPiから写真撮影
カメラで撮影するプログラムをPythonでかきます。
基本のコードはこの本を参考にさせていただきました!神!
工夫したところは、お留守番中夜でも写真が撮れるように赤外線カメラを設置したところと、
部屋が暗い時(光センサーで判定)にはシャッタースピードを遅くし撮影しています。
光センサーは、I2Cを使っていますが、RaspberryPiでは初期状態では有効になっていません。
ライブラリーをインストールします。
$ sudo apt-get install i2c-tools libi2c-dev python-smbus python3-smbus
その後、RaspberryPiの本体のメニュー[Menu]-[設定]-[RaspberryPiの設定]-[インターフェース]-[I2C]を有効に設定します。
# coding:utf-8
import smbus
import os
#光センサーで明るさを取得
def getLight():
bus = smbus.SMBus(1)
addr = 0x23
luxRead = bus.read_i2c_block_data(addr,0x11)
return luxRead[1]*10
def takePicture():
lux = getLight()
if lux < 200:
#写真撮影
os.system('raspistill -o /home/pi/..../...../images/photo.jpg -rot 90 -w 1000 -h 1000 -ss 1000000')
else:
#写真撮影
os.system('raspistill -o /home/pi/..../...../images/photo.jpg -rot 90 -w 1000 -h 1000')
if __name__ == '__main__':
takePicture()
RaspberryPiから温度取得
温湿度センサーDHT22から温度取得します。
1.ライブラリをインストールします。
$ git clone https://github.com/adafruit/Adafruit_Python_DHT.git
$ cd Adafruit_Python_DHT/
$ sudo python setup.py install
2.温度を取得するプログラムを作成します。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Adafruit_DHT
def getTemperature():
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 4)
if humidity and temperature:
return temperature
else:
return -100
def createTweetMessage():
t = getTemperature()
if t == -100:
msg = "今のくるみのお部屋の温度はわからないです。ごめんなさい~"
else:
msg = "今のくるみのお部屋の温度は{0:0.1f}度です。"
return msg
if __name__ == '__main__':
msg = createTweetMessage()
print msg
SlackとRaspberryPiの連携
Slackへ部屋の温度を投稿
### Slackの設定
1.下記ページをクリックし、Incoming WebHooksを有効化します。
### Slackへ投稿するモジュールをインストール
$ sudo pip install slackweb
### 温度取得プログラムを改修
1.「RaspberryPiから温度取得」で作成したプログラムgetTemp.pyを改修し、Slackへ温度を投げるプログラムを追加します。
また、温度によってくるみちゃんのコメントを変えます。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import slackweb
import Adafruit_DHT
def getTemperature():
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 4)
if humidity and temperature:
return temperature
else:
return -100
def createTweetMessage():
t = getTemperature()
if t == -100:
msg = "今のくるみのお部屋の温度はわからないです。ごめんなさい~"
elif t >= 30:
msg = "今のくるみのお部屋の温度は{0:0.1f}度です。".format(t) + "暑すぎですう。今すぐクーラーをいれてください!!"
elif t >= 28:
msg = "今のくるみのお部屋の温度は{0:0.1f}度です。".format(t) + "暑くなってきたのでそろそろクーラー入れてほしいですう。"
elif t >= 25:
msg = "今のくるみのお部屋の温度は{0:0.1f}度です。".format(t) + "そんなに暑くないですう。"
elif t >= 22:
msg = "今のくるみのお部屋の温度は{0:0.1f}度です。".format(t) + "今日は涼しいですう。クーラーはいらないかなー。"
elif t >= 18:
msg = "今のくるみのお部屋の温度は{0:0.1f}度です。".format(t) + "ちょっと寒くなってきました~。"
elif t >= 14:
msg = "今のくるみのお部屋の温度は{0:0.1f}度です。".format(t) + "暖かい場所が恋しいですう。"
else:
msg = "今のくるみのお部屋の温度は{0:0.1f}度です。".format(t) + "寒いよー。暖房つけてほしいですー!"
return msg
if __name__ == '__main__':
msg = createTweetMessage()
#SlackのWebhook URLを使用します。
slack = slackweb.Slack(url="https://hooks.slack.com/services/xxxxxxxxx/xxxxxxxxx/xxxxxxxxxxxxxxxxx")
slack.notify(text=msg)
2.cronに登録して1時間に1回Slackへ投稿する
$ crontab -e
0 * * * * python /home/pi/.../.../postTemp.py
3.結果!
Slackからカメラ撮影する・エアコンをつける
RaspberryPiにHubotを導入〜SlackへHubot追加
こちらのページがわかりやすくまとまっていましたので、参考にさせていただきました!ありがとうございます!!!m(_ _)m
Raspberry Pi | 自作Slackボットを作ろう~その2~ HubotのインストールとSlack連携(Herokuは使わない)
くるみちゃん(Hubot)に話しかけてカメラの撮影
bot/scriptsの下に、スクリプトを置いておくと自動で読み込んでくれるようなので、ここにCoffeeScriptで書いたコードを配置します。
hild_process = require 'child_process'
module.exports = (robot) ->
#カメラ
robot.respond /.*カメラ.*/i, (msg) ->
#「カメラで撮影するプログラムをPythonでかく」で記載したtakePicture.pyを実行する
child_process.exec "python /home/pi/..../......./takePicture.py", (error, stdout, stderr) ->
if !error
try
filename = '/home/pi/..../......./images/photo.jpg'
channel = msg.message.room
msg.reply "今のくるみはこんな感じです。"
child_process.exec "curl -F file=@#{filename} -F channels=#{channel} -F token=#{process.env.HUBOT_SLACK_TOKEN} https://slack.com/api/files.upload", (err, stdout, stderr) ->
catch e
msg.reply "#{e}"
else
msg.reply "#{error}"
return
話しかけた結果はこんな感じでくるみちゃんが写真をアップロードしてくれます!
くるみちゃん(Hubot)に話しかけてエアコンのオンオフ
child_process = require 'child_process'
module.exports = (robot) ->
#暖房
robot.respond /.*暖房オン.*/i, (msg) ->
# ここのコマンドは、本記事の「赤外線送信コマンド」のものを設定します。
# 冷房オン、オフもここのコマンドを変更することで対応可能です。
child_process.exec "irsend SEND_ONCE aircon warm24", (error, stdout, stderr) ->
if !error
try
if msg.message.user.name is "<Slackの自分のID(msg.message.user.name)>"
name = "ママさん"
else
name = "パパさん"
msg.reply "#{name}、暖房つけました!"
catch e
msg.reply "#{e}"
else
msg.reply "#{error}"
return
話しかけた結果は、わかりにくいですが、返事をして暖房をつけてくれます。
CoffeeScriptでつまずいたところ
CoffeeScriptを初めて使いましたが、しょーもないところでつまずいたので、記録しておこうと思います。
デバッグ方法
変数などをデバッグする場合、このように書くそうです。
robot.logger.debug "channel is: #{channel}"
ログはどこに書かれているかというと、
$ forever list
info: Forever processes running
data: uid command script forever pid id logfile uptime
data: [0] JZT8 coffee node_modules/.bin/hubot -a slack 15490 22705 /home/pi/.forever/JZT8.log 0:3:39:16.813
↑この例だと、「/home/pi/.forever/JZT8.log」になります。
よって、
$ tail -f /home/pi/.forever/JZT8.log
でログを確認できます。
SyntaxError修正方法
左側にコードを貼り付けると、右側にJava Scriptに変換してくれて、SyntaxErrorが何行目でおきているかわかりやすくなりました。便利!
最後に
Slackを使って、ペットの見守りシステムを構築してみました。
RasperryPi1つでここまで出来て、便利に毎日使っています!
くるみちゃんも健康を維持できてます。
おしまい。