マンションの一階に住んでいるんですが、
日が落ちても窓のシャッターを閉め忘れることがよくある。
通りに面しているので、外から部屋が丸見え。恥ずかしい。
ということで、暗くなったら自動的にシャッターが閉まるスマートホームを目指します。
使うもの
- Raspberry pi Zero W
- 照度センサ(BH1750FVI)
- Switch Bot
うちの窓シャッターはPush式で自動開閉できるので、Switch Botをくっつけて遠隔操作できるようにしています。
上下のボタンを押すとシャッターが自動で開閉してくれます。
Switch Botは専用アプリで定時実行ができるので、
開けるときはタイマーで朝7時になると自動的にPushするようになっています。
閉めるときもタイマーでもいいのですが、季節によって6時で暗かったり8時でも明るかったりして難しい・・・。
そこを照度センサを使ってうまくやれないかと。
ちなみにSwitch Bot Hubを導入すれば、IFTTTや各種スマートスピーカとも連携可能ですが、
PythonでON/OFFできるスクリプトが公開されているので、今回はRaspberryPiで実装します。
やったこと
- RaspberryPi初期設定(省略)
- 照度センサの接続・計測値グラフ化
- Switch Bot動作確認
- センサの値をトリガーにボタンON/OFF
全体像
RaspberryPi初期設定(省略)
こちらの方法はネットにたくさんあるので割愛させていただきます。
主にやったこととしては、OSの書込/Wifi設定/ssh接続ぐらいです。
ちなみにOSはRaspbian GNU/Linux 9.9 (stretch)でした。
照度センサの接続
まずは窓際にセンサを置いて明るさを測ってみます。
照度センサはBH1750FVIです。amazonで3個600円くらいで売ってます。
照度センサとRaspberry piを繋いできます。
こちらのページを参考にしました。
BH1750FVIはI2C通信をするので、RaspberryPiのI2C通信設定をONにしておきます。
$ sudo raspi-config
[5.Interfacing Options] -> [P5 I2C] -> [enable]でOK
次にi2c-toolsというI2C接続を確認するツールを導入します。
$ sudo apt-get install i2c-tools
$ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- 23 -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
0x23
アドレスに接続が確認できました。
先ほどのページにbh1750.py
というサンプルコードがあるので使ってみます。
$ wget https://bitbucket.org/MattHawkinsUK/rpispy-misc/raw/master/python/bh1750.py
$ sudo apt-get install python-smbus
$ python bh1750.py
Light Level : 66.67 lx
Light Level : 29.17 lx
Light Level : 22.50 lx
Light Level : 30.00 lx
Light Level : 33.33 lx
Light Level : 21.67 lx
Light Level : 30.00 lx
Light Level : 32.50 lx
...
ちゃんと取得できていますね
計測値グラフ化
次に、1日の明るさの推移をみるために、グラフ化します。
Focuslightというグラフ化ツールが便利そうだったのでこちらを使います。
インストール方法
FocuslightのGithubを参考にインストールします。
まずは必要なパッケージを入手
$ sudo apt-get install rrdtool librrd-dev libsqlite3-dev default-libmysqlclient-dev
Gem packageでインストール
$ gem install focuslight
$ focuslight new
$ cd focuslight
$ focuslight init # creates database scheme on SQLite
$ focuslight start
照度データを送るスクリプトを書く
#!/usr/bin/python
import commands
import smbus
bus = smbus.SMBus(1)
addr = 0x23
lux = bus.read_i2c_block_data(addr,0x11)
lux_output = commands.getoutput("curl -F number=" + str((lux[0]*256+lux[1])/1.2) + " http://localhost:5125/api/home/sensor/lux")
print lux_output
forcuslightの.env
ファイルでfloatを有効にしておく
...
FLOAT_SUPPORT=y
...
forcuslightを起動した状態で、動作確認
$ python sendLightData.py
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 547 100 402 100 145 355 128 0:00:01 0:00:01 --:--:-- 355
{"error":0,"data":{"id":1,"service_name":"home","section_name":"sensor","graph_name":"lux","number":55,"description":"","sort":0,"created_at":"2019/07/13 22:08:48","updated_at":"2019/07/13 22:28:47","mode":"gauge","color":"#9933cc","ulimit":1000000000000000,"llimit":-1000000000,"type":"AREA","adjust":"*","adjustval":"1","unit":"","complex":false,"md5":"c4ca4238a0b923820dcc509a6f75849b","meta":null}}
毎分動作するようにcronを設定
...
* * * * * root /usr/bin/python /[user_loacal]/sendLightData.py
cronの再読み込み
$ sudo service cron rload
http://localhost:5125
にアクセスすると以下のようにグラフが生成されています。
Switch Bot動作確認
Switch Botは専用アプリから操作するのが基本ですが、
公式からpythonで動作するpython-hostが公開されています。
まずは動作確認。
必要なパッケージをインストールします。
$ sudo apt-get update
$ sudo apt-get install python-pexpect
$ sudo apt-get install libusb-dev libdbus-1-dev libglib2.0-dev
$ sudo apt-get install libudev-dev libical-dev libreadline-dev
$ sudo pip install bluepy
$ git clone https://github.com/OpenWonderLabs/python-host.git
アプリからSwirchBotのMACアドレスがわかるので、それをメモしておきます。
python-host
内のswitchbot.py
を叩く。
$ sudo python switchbot.py [MACアドレス] Press
Preparing to connect.
Trigger complete
Trigger completeと出てSwitchBotが動いたので動作OKです。
センサの値をトリガーにボタンON/OFF
bh1750.py
を参考に実装していきます。
#!usr/bin/python
import smbus
import subprocess
import json
DEVICE = 0x23 # I2C address
bus = smbus.SMBus(1) # Rev 2 Pi uses 1
def convertToNumber(data):
result = (data[1] + (256 * data[0])) / 1.2
return (result)
def readLight(addr):
data = bus.read_i2c_block_data(addr,0x11)
return convertToNumber(data)
def main():
lightLevel = readLight(DEVICE)
prevLightLevelStr = subprocess.check_output("curl -s http://localhost:5125/xport/home/sensor/lux?t=sh",shell=True)
prevLightLevel = json.loads(prevLightLevelStr)
pLL1 = float(prevLightLevel['rows'][-4][0]) # 3分前
pLL2 = float(prevLightLevel['rows'][-3][0]) # 2分前
pLL3 = float(prevLightLevel['rows'][-2][0]) # 1分前
# 条件を満たしたらSwitch botを動作させる
if (pLL1 >= 100) & (pLL2 < 100) & (pLL3 < 100):
press = subprocess.call("sudo python [fullpass]/switchbot.py [MACアドレス] Press",shell=True)
# 値をfocuslightに送る
lux_output = subprocess.check_output("curl -s -F number=" + str(lightLevel) + " http://localhost:5125/api/home/sensor/lux",shell=True)
if __name__=="__main__":
main()
照度の値が100以上のあとに2回連続で100未満だったらSwitchBotを動かすようにしています。
もっと良い条件設定があったら、ぜひ教えてください。。。
またSwitchBotの動作もスクリプトを組み込まずにsubprocessで強引に動かしています。
諸々、雑なところが残りますが、とりあえずこちらを定時実行します。
...
* * * * * root /usr/bin/python /[user_loacal]/autoSwitch.py
2〜3日窓際においといたら、おうちに帰るころにはちゃんとシャッターがしまってました。
やったね!
おわりに
Raspberry Pi Zeroでもおうちハックできました!
私の家は自動シャッターだったのでSwitchBotを利用しましたが、
自動でカーテンを操作するデバイスもあるようなので応用できそうですね。
SwitchBotはひとつ4000円くらいしますが、押すだけでなく「引く」こともできるので、
よくあるパチパチ切り替えるスイッチにも使えます。デザインもかわいいのでオススメ。
それでは、よいおうちハックを!