スマートコンセント(スマートプラグ)を買いました。
- リビングにあるフロアライトを自動化したかった。
- Hueでも良いがをたくさん買うことになり金額がつらい。
- Amazonで調べてみるとスマートコンセントなら数千円で購入できるらしい。
- こいつをHackすれば良いのでは?
- 安いコピー商品的なのがめっちゃある
- その中でも色々できそうで安かったMerossというメーカーのスマートコンセントを買いました。
- 2つ入りで2,599円だった也
- IFTTT連携もあるんだけど数秒遅延するので、やっぱRaspberryPiから直接操作したい。
Charlesで通信を調べてみる
iOSアプリの設定を済ませて、どんな通信をしているのか覗いてみました。
payload.togglex.onoff
ってやつが怪しい
sign
とか messageId
の生成ルールが解析できないと詰みそう・・・
とりあえずそのままCurlで送ってみる
$ 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で切り替えるとチカチカできる。
sign
や messageId
も使い回せた。。。
headerにもBasic認証っぽいやつとかもあったけど、使わないでも通信できた。。。
セキュリティ的には気になるけど、結果的にはOK
人感センサーでライトを操作したい。
ということで本命の、
部屋に人いるときはライトを点けて、いなくなったら消すって装置を作っていきます。
材料。
- Raspberry Pi
- 焦電型赤外線センサーモジュール(焦電人感センサ) SB612A
人感センサーの値を取得したい。
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
センサーの前に立って動いている最中に1が返ってってくればOK
スマートコンセントに送るプログラム。
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分間何もなかったらライトを切るという仕組みです。
ライトの麓に置いておいた。
近寄ってみる。
おわり。
もしかしてルンバに反応してしまうんじゃ、と思ったけど意外と大丈夫だった。
そこまで熱くないか