スマートコンセントをHackして普通のフロアライトを人感センサーで点灯するようにしてみた

# スマートコンセント（スマートプラグ）を買いました。
- リビングにあるフロアライトを自動化したかった。
- Hueでも良いがをたくさん買うことになり金額がつらい。
- Amazonで調べてみるとスマートコンセントなら数千円で購入できるらしい。
- こいつをHackすれば良いのでは？
- 安いコピー商品的なのがめっちゃある
- [その中でも色々できそうで安かったMerossというメーカーのスマートコンセントを買いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/270801a3-f9d1-5004-185f-243594cbf291.png)](https://amzn.to/2Kdd9TL)
- ２つ入りで2,599円だった也
- IFTTT連携もあるんだけど数秒遅延するので、やっぱRaspberryPiから直接操作したい。


## Charlesで通信を調べてみる
iOSアプリの設定を済ませて、どんな通信をしているのか覗いてみました。

![Artboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/7d292791-c389-6f7f-c1be-c51b549b7c87.png)

`payload.togglex.onoff` ってやつが怪しい
`sign` とか `messageId` の生成ルールが解析できないと詰みそう・・・


### とりあえずそのままCurlで送ってみる

```bash
$ curl --request POST \
  --url http://172.16.00.000/config \
  --header 'content-type: application/json' \
  --data '{
	"payload": {
		"togglex": {
			"onoff": 1,
			"channel": 0
		}
	},
	"header": {
		"messageId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
		"method": "SET",
		"namespace": "Appliance.Control.ToggleX",
		"timestamp": 1556035842,
		"sign": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
		"payloadVersion": 1
	}
}'
```

カチッて音とともにライトが点いた。
普通に操作できてしまった。


### onoffを1と0で切り替えるとチカチカできる。
![blink.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/c5b3e09b-3110-7b38-f4cc-528306266930.gif)

`sign` や `messageId` も使い回せた。。。
headerにもBasic認証っぽいやつとかもあったけど、使わないでも通信できた。。。
セキュリティ的には気になるけど、結果的にはＯＫ


## 人感センサーでライトを操作したい。
ということで本命の、
部屋に人いるときはライトを点けて、いなくなったら消すって装置を作っていきます。


### 材料。
- Raspberry Pi
- 焦電型赤外線センサーモジュール（焦電人感センサ） [SB612A](http://akizukidenshi.com/catalog/g/gM-08767/)


### 人感センサーの値を取得したい。

![Untitled Sketch_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/b245cf34-7537-96b3-d945-0fa0450e9110.png)
ラズパイの5V・17番・GNDとセンサーを繋げます。


```python:test.py
import RPi.GPIO as GPIO
import time

PIN = 17

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN, GPIO.IN)
GPIO.setwarnings(False)

count = 0

while True:
    res = GPIO.input(PIN)
    print(res)
    time.sleep(1)
```

#### 実行！

```
$ python test.py
0
0
0
0
1
1
1
1
1
1
1
```

センサーの前に立って動いている最中に１が返ってってくればＯＫ


### スマートコンセントに送るプログラム。

```python:main.py
import RPi.GPIO as GPIO
import time
import requests

PIN = 17
URL = "http://172.16.00.000/config"

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN, GPIO.IN)
GPIO.setwarnings(False)

count = 0

try:
    while True:
        res = GPIO.input(PIN)
        if res == 1:
            if count < 0:
                count = 0
            else:
                count += 1
        else:
            if count > 0:
                count = 0
            else:
                count -= 1

        if count == -3000:
            payload = "{\n\t\"payload\": {\n\t\t\"togglex\": {\n\t\t\t\"onoff\": 0,\n\t\t\t\"channel\": 0\n\t\t}\n\t},\n\t\"header\": {\n\t\t\"messageId\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n\t\t\"method\": \"SET\",\n\t\t\"namespace\": \"Appliance.Control.ToggleX\",\n\t\t\"timestamp\": 1556029697,\n\t\t\"sign\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n\t\t\"payloadVersion\": 1\n\t}\n}"
            headers = {'content-type': 'application/json'}
            response = requests.request("POST", URL, data=payload, headers=headers)
            print("send off", response.ok)

        if count == 10:
            payload = "{\n\t\"payload\": {\n\t\t\"togglex\": {\n\t\t\t\"onoff\": 1,\n\t\t\t\"channel\": 0\n\t\t}\n\t},\n\t\"header\": {\n\t\t\"messageId\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n\t\t\"method\": \"SET\",\n\t\t\"namespace\": \"Appliance.Control.ToggleX\",\n\t\t\"timestamp\": 1556029697,\n\t\t\"sign\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n\t\t\"payloadVersion\": 1\n\t}\n}"
            headers = {'content-type': 'application/json'}
            response = requests.request("POST", URL, data=payload, headers=headers)
            print("send on", response.ok)

        print(count)
        time.sleep(0.2)

finally:
    print("error")
    GPIO.cleanup()
```

0.2秒ずつセンサーの値を取得し、
2秒間連続でセンサーが反応したらライトを点け、
10分間何もなかったらライトを切るという仕組みです。


### ライトの麓に置いておいた。
![IMG_3788.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/c6f46cc0-edb1-890e-ace0-715c71e3f080.jpeg)

### 近寄ってみる。
![walk.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/b72a4807-8679-7f0e-92c0-686278c6ea85.gif)

## おわり。
もしかしてルンバに反応してしまうんじゃ、と思ったけど意外と大丈夫だった。
そこまで熱くないか