概要
100円ショップのダイソーでは、スマホのカメラのシャッターを遠隔操作するためのBluetoothカメラシャッターボタンが売っています。
これは300円ほどとお安く入手できるもので、なかなか面白いオモチャです。
今回はこのBluetoothボタンをIoTボタンとして転用してみることにします。
仕組みとしては、ボタンを押したらPythonとRaspberry Piでそのボタンの押下を検知し、任意のWEB APIにGETメソッドでコールすることで、自由に遊べるという感じ。
なお筆者はトイレに行ったタイミングでこのIoTボタンを押して、何時何分にトイレに行ったかデータをDBに記録しています。
コード
devinoue/300yen-iot-button
GitHubにてコードを公開してます、スターをよろしくお願いします!
環境
環境はRaspberry Piの使用を推奨。
- Raspberry Pi 3 Model B+
- Python 3.6
- pip 9.0.1
Bluetoothボタンの準備
まずリモートシャッターとRaspberry Piをペアリングをします。
リモートシャッターをONについて、Raspberry Piで以下のコマンドを実行します。
bluetoothctl
scan on
おそらく[NEW] Device XX:XX:XX:XX:XX:XX AB Shutter3
という名前とMACアドレスが表示されるので、このMACアドレスでpairingと自動再接続されるようtrustを実行します。
pair XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
成功したら終了しましょう。
exit
必要なモジュールのインストール
evdevというモジュールを使用しています。
以下のコマンドでインストールしてください。
sudo pip3 install evdev
実行
以下がコードのすべてです。evdevでキーの動作を検知しています。
長押し検知機能もあるので、計4つのAPIエンドポイントにコールすることができます。
標準出力にはレスポンスデータが表示されます。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Python IoT Button"""
import evdev
from evdev import InputDevice, categorize, ecodes
import datetime
from time import time, sleep
from urllib import request, error
import settings
# 送信先URL
# iOSボタンを押したとき
url_iOS_push = "https://postman-echo.com/get?from=ios_push"
# iOSボタンを長押ししたとき
url_iOS_hold = "https://postman-echo.com/get?from=ios_hold"
# Androidボタンを押したとき
url_Android_push="https://postman-echo.com/get?from=android_push"
# Androidボタンを長押ししたとき
url_Android_hold="https://postman-echo.com/get?from=android_push"
# ホールドされたとみなす時間(秒)
hold_time_sec = 0.5
def main():
print("Waiting for device to become ready...")
dev_path = ""
while(True):
devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
for device in devices:
if("Shutter" in device.name):
dev_path = device.path
if (dev_path == "") :
sleep(1)
else : break
dev = InputDevice(dev_path)
print("IoT Button is ready.")
old = 0
iOS_flag=0
is_android = 0
for event in dev.read_loop():
if event.type == ecodes.EV_KEY:
if event.value == 1:
if event.code == 28: # when android button pushed
is_android=1
# key upが始まったら
if event.value == 0:
if iOS_flag==1 :
iOS_flag=0
continue
# 長押し終わり
if old != 0 and time() - old > hold_time_sec:
if is_android :
ConnectServer(url_Android_hold,"Android hold")
is_android=0
iOS_flag=1
else:
ConnectServer(url_iOS_hold,"iOS hold")
old = 0
continue
if is_android:
ConnectServer(url_Android_push,"Android push")
is_android=0
iOS_flag=1
else:
ConnectServer(url_iOS_push,"iOS push")
# 長押しスタート
if event.value == 2 and old == 0:
old = time()
def ConnectServer(url,style):
req = request.Request(url)
try:
with request.urlopen(req) as res:
print("Success : {} {}".format(style,res.read(100).decode('utf-8')))
except error.HTTPError as err:
print(err.code)
except error.URLError as err:
print(err.reason)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
print("\n")
終わりに
Raspberry Piで楽々IoTボタンライフをお過ごしください