강좌 전체보기

.

이번 장에서는 1~6 장에서 다룬 통신 방법과 제어코드를 활용해서 사물인터넷  서비스 하나를 만들어 보겠습니다. 이런 예제 서비스를 만들 때 가장 먼저 생각나는건 홈 오토메이션이죠. 여기서도 홈 오토메이션을 주제로 한 서비스를 구현해 볼 예정입니다.

홈 오토메이션 서비스 기획

Tech DIY 등을 하다보면 가장 흔하게 선택하는 주제가 생활 주변의 가전들, 그리고 실내에서 가지고 노는 장난감들 입니다. 그래서 이런 DIY  작품들을 업그레이드 하다보면 자연스레 홈 오토메이션과 연결되기 마련입니다.

예를 들어, 요즘 화두가 되곤하는 미세먼지에 착안해서 미세먼지 측정기를 만들고, 공기청정기가 미세먼지 센서에 연동해서 돌아갈 수 있도록 만들었다고 가정해보죠. 그럼 자연스럽게 공기청정기를 사물인터넷 서비스에 연결하고 싶어집니다. 미세먼지 센서의 값은 서버에 저장해서 언제 어디서든 핸드폰으로 확인할 수 있도록 만들고, 핸드폰에서 공기청정기의 동작을 제어하도록 만들고 싶어지겠죠.

하지만 이런 서버 구현이 어려운 사람들을 위해 범용 사물인터넷 서비스들이 생겨났습니다. 대표적인 것이 ThingSpeak 입니다.

ThingSpeak 서비스에 가입하면 채널(channel)을 생성할 수 있습니다. 이 채널이 데이터 저장소 역할을 합니다. 우리가 만든 미세먼지센서-공기청정기가 있다면, 미세먼지 센서의 값을 이 채널로 보내면 됩니다. 그러면 핸드폰이나 PC의 브라우저에서 생성한 채널의 URL 로 접속해서 누적된 값으로 그려진 그래프를 볼 수 있습니다. 또한 채널이 제공하는 API 를 호출해서 데이터를 가져와 원하는대로 가공해서 쓸 수도 있습니다.

즉, ThingSpeak 서비스는 Tech DIY 나 사물인터넷 데모 버전을 만들다보면 가장 흔히 겪는 목마름을 해소해주는 도구입니다. 그래서 이번 장에서 만들 홈 오토메이션 예제도 ThingSpeak 와 유사하게 동작하는 예제로 잡았습니다.

우선 예제 서비스가 동작할 대강의 구조를 잡아보겠습니다.

센서 장치가 수집하는 데이터는 서버로 전달되어 저장되고, 서버의 데이터는 다양한 사용자 장치에서 볼 수 있습니다. 반대로, 사용자 장치에서 명령어를 서버로 전송하면 서버는 다시 명령어를 센서 장치로 전송해 줍니다.

이제 ThinkSpeak 서비스를 참고해서, 좀 더 상세한 동작 시나리오를 그려 보겠습니다.

  • 웹 페이지를 통해 채널(channel) 생성
  • 채널이 생성되면 인증 코드를 발급
  • 각 채널은 1개의 센서 데이터를 저장
  • 각 채널에 센서 데이터 입력을 위해 외부에서 호출가능한 data input API 제공
  • 센서장치는 data input API 를 호출해서 데이터 입력 가능 (인증코드와 데이터를 함께 전송)
  • 서버는 각 채널로 입력되는 데이터를 DB에 저장
  • 각 채널의 데이터를 그래프로 표시해주는 웹 페이지 제공
  • 그래프 페이지에서 버튼을 눌러 명령어를 센서장치로 전송 가능
  • 외부 장치에서 각 채널 데이터를 검색 할 수 있는 query API 제공

동작 시니라오대로 작동하기 위해서는 홈 오토메이션 서비스가 아래와 같은 웹 화면들을 제공해야겠지요.

[채널 선택, 등록 화면]

[등록(생성) – 채널 이름 설정]

[채널 등록 후 인증 코드 발급]

[채널 선택 – 그래프 확인 화면]

자, 대강의 서버 구현 계획은 세워졌습니다. 그럼 실제 서비스가 동작하기 위해 필요한 기술적인 요소들을 선택하고, 상호 데이터를 주고 받을 때 사용할 데이터 형식을 정해 보겠습니다.

홈 오토메이션 예제의 상세 구현 계획

서버

예제 구현을 위해 가장 중요한 역할을 하는 것은 서버입니다. 서버는 센서장치에 data input API 를 제공해서 데이터를 수집 저장하고, 다양한 플랫폼을 사용하는 사용자에게 데이터를 보여줄 수 있는 방법을 제공해줘야 합니다.

우리는 사용자에게 웹 페이지 형식으로 데이터를 보여줄 겁니다. 웹 페이지 형식을 사용하면 사용자가 어떤 플랫폼을 쓰든 브라우저를 통해 서비스를 사용할 수 있는 장점이 있습니다. 대신 웹 서버를 구축해야겠죠.

또한, 서버는 모바일 앱이나 기타 다른 어플리케이션을 위해 웹이 아닌 API 형식으로 데이터를 추출할 수 있도록 해줄겁니다. 그래야 단순히 현재 데이터를 확인하는 것을 넘어 더 다양한 처리를 해서 사용자에게 보여줄 수 있으니까요.

이런 요구사항들을 감암하면 서버는 라즈베리파이에 node.js 를 이용해서 구현하는 것이 편리합니다. node.js 를 사용하면 웹 서버 구축 뿐 아니라 센서장치와 사용자 앱이 사용할 API 만들기도 쉽습니다. 널리 사용되는 서버 플랫폼이라 관련된 모듈, 자료 구하기도 쉽구요.

센서장치

센서장치가 서버로 데이터를 전달하기 위해 WiFi 모듈을 사용할겁니다. 우리가 만드는 센서장치는 대부분 사용자의 위치와는 무관하게 스스로 계속 데이터를 수집하면서 동작해야 합니다. 따라서 블루투스는 이런 환경에서 사용하기가 힘듭니다.

센서장치는 서버로 데이터를 보낼 때 HTTP POST 를 사용하도록 하겠습니다. 이때 HTTP body 안에 JSON 형식으로(application/json) 데이터를 담아 보내겠습니다.

{
  "channel": 채널넘버,
  "auth_code": "채널인증코드",
  "data": 숫자데이터
}

사용자가 웹 페이지를 통해 채널을 생성하면 채널 번호와 채널 인증코드가 발급됩니다. 이 값을 사용해서 센서가 업데이트 할 채널을 지정하고, 숫자로 된 데이터를 함께 담아 보내도록 만들겠습니다.

그런데 여기에 문제가 하나 있습니다. 사용자가 커맨드를 서버로 전송하면, 서버는 다시 센서장치에게 커맨드를 보내줘야 합니다. 센서장치가 이 커맨드를 받으려면 어떻게 해야할까요? 현재 센서장치에 들어온 커맨드가 있는지 HTTP request 를 빠르게 계속 서버로 보내서 체크해야 할까요? 이런 polling 방식은 굉장히 비효율적입니다. 언제 그리고 얼마나 자주 커맨드가 들어올지 모르는데 계속 서버에 HTTP request 를 보낸다면, 센서장치가 증가할수록 부하가 급증합니다. 따라서 서버 push 방식의 해결책이 필요합니다.

이 때 생각해 볼 수 있는 (그리고 우리가 다뤘던), push 가 가능한 통신 방법은 웹 소켓과 MQTT 입니다. 여기서는 많은 수의 센서장치를 효율적으로 관리하기 위해 MQTT를 사용하도록 하겠습니다. 센서장치는 MQTT 브로커에 접속하고, [채널넘버/status] 토픽을 구독(subscribe)해서 0(off) 또는 1(on) 제어신호를 받도록 하겠습니다.

모바일 폰

센서장치와 서버가 동작하면, 데이터는 서버에 차곡차곡 쌓일겁니다. 사용자는 웹 브라우저만 있으면 서버에 접속해서 데이터를 확인할 수 있고, 명령어를 보낼 수도 있습니다.

따라서 홈 오토메이션 서버의 주소만 북마크 해두고 사용하면 간단하게 사용자 UI 가 해결됩니다. 이걸 좀 더 세련되고 만들고 싶으면, 안드로이드나 iOS 전용 앱을 만들면 됩니다. 전용 앱은 WebView 를 사용해서 서버의 웹 페이지를 보여주기도 하고, 채널과 인증코드를 이용해서 서버 API 에서 데이터를 읽어와 그래프로 그려줄 수 있죠. 또한 명령어는 MQTT를 이용해 직접 보낼 수도 있습니다. 이걸 조합하면 폰이 특정 상태일 때 센서장치의 동작을 제어하도록 자동화 할 수도 있죠. (물론 서버에서 이 작업을 해도 되고, 그 편이 더 효율적이지만…)

단, 모바일 폰에서 MQTT 를 사용할 때는 주의할 점이 하나 있습니다. 모바일 폰은 특성상 사용자 입력 없이 오래 대기하면 power save 모드로 진입합니다. 그리고 이 때는 framework 에서 강제로 HTTP 통신을 끊는 등 background 로 동작하는 작업에 지장이 생기는 경우가 많습니다. MQTT 는 socket 통신을 사용하기 때문에 두 장치가 계속 연결되어 있는 상태를 가정합니다. 모바일 폰의 framework 에서 여기에 제한을 걸면 앱에서 백그라운드로 MQTT 작업을 할 수 없는 경우가 생깁니다.

이제 어떻게 홈 오토메이션 서비스를 구현할지 계획이 모두 세워졌습니다. 요약하자면 아래와 같은 구조로 되겠지요.

다음 파트부터 하나씩 차근차근 구현해 보겠습니다.

참고자료

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

강좌 전체보기

.