ずいぶん前にお遊びでダイソーのbluettothシャッター(AB Shutter)とラズパイでちょこちょこ遊んでた。
doroyamada.hatenablog.jp
で、引っ越しを機に寝室にスマート電球を導入した。
スマートフォンのアプリやGoogleHomeでコントロールしているけど、指でつけたり消したりしたい場面もある。そこでお蔵入り状態だったシャッターとおうちサーバとの連携でつけようと考えた次第。bluebuttonというrubyライブラリで簡単にできそう。
CUIでのペアリングは問題なくできた。しかしbluebuttonがインストールできない。「ruby2以上が必要なんやけど、ruby3やないか」という意味不明なエラー。
ひととおり検索してみたが解決できず。しょうがないので、bluetoothがペアリングされたらオンにするという設定にしてみた。1秒毎に接続を確認して、接続されていたら電源オンのjsonを電球のローカルIPアドレスに投げる。
<?php include(__DIR__ . "/include.php"); $count = 0; while(true){ if(file_exists("/dev/input/event10")){ $count++; if($count == 1){ echo "light\n"; $context = stream_context_create($opts); file_get_contents($target, false, $context); } echo "$count\n"; }else{ echo "disconnected\n"; $count = 0; } sleep(1); } ?>
なんとか動くようになった。サービスにも登録。
でも消すのもボタンでやりたい。bluebuttonを使わずに入力ディバイスの監視をする方法を調べていたら発見。
monomonotech.jp
pythonライブラリか。ワシにとってはハードル高いけど、こちらのスクリプトをベースにやってみる。試行錯誤の末にできあがったのがこんなスクリプト。普通のプッシュでオン、1秒以上の長押しでオフになる。ディバグ用のメッセージは残してある。
#!/usr/bin/env python3 import evdev import time import requests,json def meross_bulb(switch): url = 'http://192.168.1.xxx/config' #JSON形式のデータ json_data = { 省略 } #POST送信 response = requests.post( url, headers = {'Content-Type': 'application/json'}, data = json.dumps(json_data) ) res_data = response.json() return res_data while True: try: device = evdev.InputDevice('/dev/input/event10') print(device) for event in device.read_loop(): if event.type == evdev.ecodes.EV_KEY: if event.value == 1: # 0:KEYUP, 1:KEYDOWN print(event.code) if event.code == 115: print(f"down!") ut_push = time.time() if event.value == 0: print(f"up!") interval = time.time() - ut_push print(interval) if interval >1: print(f"long push") meross_bulb(0) else: print(f"short push") meross_bulb(1) except: print('Retry...') time.sleep(1) #https://monomonotech.jp/kurage/raspberrypi/daiso_btshutter.html
このボタンは90秒弱でスリープになるので、最初はウェイクするのを数秒待たなければならないという宿命がある。
バージョンによってAndroidボタンの信号に違いがあるらしいが、手元のものはAndroidもiPhoneも同じ信号だったので、ボタンごとにオンとオフを割り当てるのはできなかった。