nodeMCU D1 mini 동작감지하여 스마트폰 또는 PC에 Push 알림 전달하기 만들기 2019.04.14 22:14

nodeMCU D1 mini와 인체 감지 센서 HC-SR501를 이용해서 사람의 동작을 감지한 다음 Pushbullet 서비스를 이용해 스마트폰과 크롬 브라우저에 Push 알림을 전달하는 프로젝트를 만들어 봤다. 철저하게 내가 필요해서 가성비 높게 쉽게 빨리 만들어서 사용할 수 있도록 만들어 봤다. 카운터를 비워두었는데, 손님이 방문 할 경우 스마트폰으로 알림이 가는 것이 핵심이다.

개별 사항은 어려운 내용이 별로 없을 것이라 생각했는데, 잘 안되서 삽질을 좀 했다. pushbullet API 서버와 https 연결이 안되어서 pushbullet에 직접 연결 할 수가 없었다. 우여곡절끝에 아주 지저분하게 만들기는 만들었는데, 절반은 실패한거나 다름없다고 생각한다.ㅠ 경험을 공유해본다.

구성과 동작 시나리오

구성과 시나리오는 간단하다. nodeMCU D1 mini(2,600원), HC-SR501(1,000원), Pushbullet(무료), 웹서버(?), 무선 AP와 인터넷!

  1. nodeMCU D1 mini에 HC-SR501를 연결하여 동작을 감지
  2. 동작이 감지되면 맛소금 웹서버로 http request
  3. 맛소금 웹서버에서 Pushbullet으로 https request 전달
  4. Pushbullet에 설정된 스마트폰등의 기기에 알림 전달

원래 2번 스텝에서 바로 Pushbullet으로 https request를 날리면 되어야 한다. 아주 깔끔하게 될 수 있는 방법이고, 해외 블로거들도 해당 방법을 소개하고 있다. 하지만 https 연결이 안되서 우여 곡절끝에 맛소금 웹서버를 이용하게 되었다. 이거 하나 할라구 웹서버를 하나 돌려야 한다니...;;;

HC-SR501을 이용하여 동작 감지

HC-SR501는 인체에서 발산되는 적외선을 감지하는 센서로써 뛰어난 가성비 때문에 널리 사용되어 IT에 관심없는 사람들도 많이 알고있다.

센서의 동작은 매우 간단하다. 동작이 감지되면 GPIO가 HIGH가 된다. 이벤트의 감도와 연속적으로 이벤트가 발생하게 할 것인지등만 고민해서 점퍼와 가변저항을 설정해주면 된다. 센서 자체에 대한 설명은 인체감지센서(HC-SR501)사용하기글을 참고하면 좋을것 같다.

나는 이벤트가 계속 들어오도록 설정하였고, 0.5초에 한번씩 GPIO를 체크하여서 동작이 감지되어 있으면 알림을 전달하도록 하였다. 알림을 전달 후 tick이라는 변수 값을 저장하도록 하였는데, 일정 시간동안 중복 알림을 생성하지 않기 위함이다.

센서에서 일정 시간동안의 offset을 설정할 수 있지만 가변저항에 의한 것보다 정확하게 컨트롤 할 수 있으므로, 센서에서는 계속 이벤트를 발생시키고 nodeMCU에서 이벤트를 거르게 한 것이다.

function startMotion()
    motion_timer:alarm(500, tmr.ALARM_AUTO, function()
        local on_off = gpio.read(gpio5_pin)
        print("Motion detection result: ", on_off, tick_count)

        if tick_count > MAX_TICK then
            tick_count = 0
        end

        if on_off == 1 then
            gpio.write(LED_pin, gpio.LOW)
            if tick_count == 0 then
                postNotification()
                tick_count = 1
            end
        else
            gpio.write(LED_pin, gpio.HIGH)
        end

        if tick_count > 0 then
            tick_count = tick_count + 1
        end
        
    end)
end

동작이 감지되면 Pushbullet으로 http request 전달

Pushbullet은 이름처럼 Push 전문 서비스다. 스마트폰이든 PC의 크롬 브라우저든 Push 알림을 주고 받으려면 알림을 전달하는 서버가 있어야 하는데 그 서버의 역할을 서비스로 제공하고, 스마트폰과 크롬 브라우저에 전용 앱을 제공해서 서버로부터 Push 알림을 수신한다. 이번에 알게된 서비스인데, 기능도 다양하고 사용도 편리하다!

우선 가입을 하고, 스마트폰에서 앱을 다운받는다. 설정에 들어가면 본인의 Access Token 을 받을 수 있다. 해당 토큰으로 간단하게 Push 알림을 생성하는 API를 사용할 수 있다!

나는 이벤트가 들어오면 REST API를 사용해서 Pushbullet에 알림을 생성하도록 하였다.

function postNotification()
    http.post('https://api.pushbullet.com/v2/pushes',
        'Content-Type: application/json\r\nAccess-Token: MY_ACCESS_TOKEN\r\n',
        '{"body":"Space Elevator, Mars Hyperloop, Space Model S (Model Space?)", "title":"Space Travel Ideas", "type":"note"}',
        function(code, data)
            print('Complete')
            print(code, data)
        end)
end

너무 쉽다! 짱이다!!!.....라고 생각했지만, 실제로는 https 연결이 안되었다. https 연결에 문제가 있다는 것도 디버그 바이너리를 설치해서 에러 메세지를 보고서야 알 수 있었다.ㅠ 개발 중엔 디버그 바이너리의 사용를 권장한다.

Alert: handshake failure
Error: SSL error 40

 

https://nodemcu-build.com/ 커스텀 빌드에서 Debug 옵션을 체크하자!

Arduino ESP8266HTTPClient: Handshake failure (SSL error 40) 이런 글이 있는데, 어째든 현재로써는 nodemcu 에서 해당 host에 https 연결을 할 수가 없는 것 같다. 그래서 AWS API Gateway와 lambda를 이용해서 조금 지저분하지만 우회 경로를 만들어 보려 했으나, API Gateway 역시 https를 사용하고 있는데, 연결이 안되었다.ㅠ 그래서 정말 지저분하게 사용중인 웹서버에 http REST API를 하나 만들어서 그걸로 프로젝트를 완성하였다.

불필요하게 별도의 서버를 돌려야 한다는 것이, 최악이라고 생각한다. 그럴거면 pushbullet 말고 다른 접근도 고려해 볼걸 그랬다. https 연결이 쉬운게 아니구나라는 것을 알게되었고, 간단해 보이는 것도 IoT에서는 어려울 수 있다는 것을 다시 깨닫게 되었다. 이왕 서버를 쓰게 된거, 텔레그램 챗봇을 만들어서 붙여볼까 생각중이다.

왜 연결이 안되는지 확인해서 정리한 글: nodeMCU Pushbullet HTTPS Handshake Fail Error: 40

Pushbullet 에서 스마트폰에 알림 전달

이 부분은 Pushbullet에서 모두 처리해주므로 내가 직접 해줘야 할 것은 아무것도 없다. 알림이 안들어오거나 소리, 진동의 설정은 각자의 타겟 디바이스의 설정과 앱 설정을 확인하면 된다.

Free accounts (without a Pro subscription) are limited to 500 pushes per month. Going over will result in an error when sending a Push.

약 4천원으로 카운터에 손님이 왔는지 확인하는 간단한 IoT 디바이스 완성했지만, 웹서버가 없이는 안된다는 점pushbullet push API는 월 500회 까지만 무료로 제공한다는 점이 큰 아쉬움으로 남았다.