ダイソーシャッターでスマート電球コントロール

 ずいぶん前にお遊びでダイソーの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も同じ信号だったので、ボタンごとにオンとオフを割り当てるのはできなかった。