LoginSignup
18
18

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-04-25

スマートコンセント(スマートプラグ)を買いました。

Charlesで通信を調べてみる

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

Artboard.png

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で切り替えるとチカチカできる。

blink.gif

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

人感センサーでライトを操作したい。

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

材料。

  • Raspberry Pi
  • 焦電型赤外線センサーモジュール(焦電人感センサ) SB612A

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

Untitled Sketch_bb.png
ラズパイの5V・17番・GNDとセンサーを繋げます。

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分間何もなかったらライトを切るという仕組みです。

ライトの麓に置いておいた。

IMG_3788.jpg

近寄ってみる。

walk.gif

おわり。

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

18
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18