2015년 8월 29일 토요일

XBee기반 홈 오토메이션 웹서버 개발

한동안 하지 못했던 스마트 홈 오토메이션 웹서버를 만들어 본다. 웹서버라고 해도 그리 대단한 건 아니다. node.js를 사용해 서버를 구현할 계획이다. 이 내용은 다음 레퍼런스를 참고한다.
참고로, 특정 센서 값을 취득하여, 서버에 저장하고, 계산하거나, 웹을 통해, 릴레이, 액추에이터 등을 제어하는 것은 모두 이 글에서 기술하는 것과 유사한 방식으로 처리할 수 있다.

1. 개요
node.js는 JavaScript 런타임 상에 개발된 플래폼으로, 쉽고 빠르게, 확장성있는 네트워크 어플리케이션을 개발할 수 있도록 지원한다. node.js는 이벤트 드리븐 구조이며, non-blocking 입출력 모델을 지원하여, 가볍고 효율적인 데이터 중싱 실시간 어플리케이션을 분산된 장치 기반에서 실행할 수 있도록 개발을 지원한다. 


node.js로 얼마나 쉽게 네트워크 어플리케이션을 개발할 수 있는 지 보자.

보통 웹서버를 개발한다면, 예전 방식은, 아파치 혹은 IIS와 같은 웹서버와 각종 웹 어플리케이션 컨테이너 프레임웍을 설치한 후, 복잡한 설정값을 맞춰줘야 한다. 그리고, 자바, C#과 같은 언어를 컴파일하고, 각종 스크립트 및 마크업언어와 메쉬업하는 작업을 해야 하는 등, 여러가지 복잡하고 짜증나는 일들이 많았다.

이제 node.js로 웹서버 어플리케이션을 개발해보자.

우선 node.js를 본인 운영체제에 맞게 설치한다.
그리고, 다음 코드를 example.js 파일로 저장한다.

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

그리고, 다음과 같이 터미널에서 실행한다.
node example.js

그리고, 클롬에서 http://localhost:1337/ 주소로 접근해 본다.


잘 동작하는 것을 확인할 수 있다.

매우 간단한 웹서버 어플리케이션을 개발해 보았다. 이런 방식으로 복잡한 기능을 지원하는 서버 프로그램도 가능하다.

2. 스마트 홈 웹서버 개발
1. XBee 개발
다음 GitHub에서 소스를 다운받아, 작업폴더 내에 압축을 풀어 놓는다.
npm (node package manager) 를 이용해, 스마트 홈 서버 개발에 유용한 몇가지 패키지를 설치해 보겠다. 다음과 같이 터미널에서 명령을 입력해, 패키지를 설치한다.

PIR 모션 센서와 XBee 쉴드를 다음과 같이 연결한다.

1. XBee 쉴드와 아두이노를 연결한다.
2. PIR 모션센서 GND / VCC와 아두이노 GND / VCC(5V)연결.
3. PIR 모션센서 OUT은 아두이노 8번 핀에 연결
4. XBee 쉴드 스위치 on / Analog In 스위치를 DLINE 으로 설정

모션센서가 제대로 동작하는 지 확인하기 위해, 다음 아두이노 코드를 실행해 본다.

// Simple motion sensor
int sensor_pin = 8;
void setup() {
  Serial.begin(9600);
}
void loop() {
  // Read sensor data
  int sensor_state = digitalRead(sensor_pin);
  // Print data
  Serial.print("Motion sensor state: ");
  Serial.println(sensor_state);
  delay(100);
}

시리얼 모니터를 실행해 보면, 다음 결과값을 확인할 수 있다. 인체가 가까이 있을 경우, 센서 상태가 1로 켜지는 것을 확인할 수 있다.



2. 아두이노 코딩
웹서버와 JSON방식으로 센서 데이터 통신을 위해 다음의 아두이노 라이브러리를 설치한다.

https://github.com/marcoschwartz/aREST

아두이노 IDE에서 다음과 같이 코딩한다.

// Libraries
#include <SPI.h>
#include <aREST.h>

// Motion sensor ID
String xbee_id = "1";
// Create ArduREST instance
aREST rest = aREST();

void setup() {
  // Start Serial
  Serial.begin(9600);
  // Give name and ID to device
  rest.set_id(xbee_id);
}

void loop() {
  // Handle REST calls
  rest.handle(Serial);
}

이후, 시리얼 모니터를 열고, 다음 명령을 입력해, XBee볻에 현재 집안에 있는 모든 XBee를 리스트하도록 한다. 
/id

현재 XBee가 하나라면, 다음과 같이 XBee가 응답한다. 
{"id": "1", "name": "", "connected": true}

센서 8번핀의 값을 획득해 본다. 
/digital/8

그럼 다음과 같이 응답할 것이다.
{"return_value": 1, "id": "1", "name": "", "connected": true}

만약 동작하지 않은 경우, PAN(Personal Area Network) 동일 ID가 아닐 경우가 있으므로, 다음 링크에서 다운받아, 동일 ID로 설정한다. 

http://www.digi.com/products/wireless-wired-embedded-solutions/zigbee-rf-modules/xctu


3. 웹서버 개발
터미널에서 xbee_motion_sensors의 interface 폴더로 이동한 후 다음과 같이 aREST 모듈을 설치할 수 있도록 명령을 입력한다.
sudo npm install arest


윈도우 운영체계라면, 명령 앞의 sudo를 제외하고 입력한다.
sudo npm install serialport

express 모듈 설치를 위해 다음 명령을 입력한다.
sudo npm install express

마지막으로, Node.js 서버를 다음 명령으로 시작한다.
sudo node app.js

app.js의 내부 소스는 다음과 같다.

// Module
var express = require('express');
var path = require('path');
var arest = require('arest');
// Create app
var app = express();
var port = 3700;
// Set views
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'views')));
// Serve files
app.get('/interface', function(req, res){
res.sendfile('views/interface.html')
});
// API access
app.get("/send", function(req, res){
arest.send(req,res);
});
// Start server
app.listen(port);

           console.log("Listening on port " + port);

app.js는 다음과 같이, 클라이언트 접속요청이 들어오면, express객체인 app의 listen함수를 호출해, 3700포트로 서버 대기 상태가 된다.

만약, url 에 /interface를 입력하면, 파일안의 html을 send해 렌더링한다.
/send url로 접속했을 때는 arest로 해당 메시지를 전달한다. 이는 아두이노에 연결된 XBee보드에 시리얼로 해당 메시지가 전달되도록 한다.

app.js 실행 후에는 터미널에서 다음 메시지를 확인할 수 있다.
Listening on port 3700

3. 테스트
이제, 웹 브라우저를 실행해, 주소창에 다음을 입력한다.
localhost:3700/interface

그럼 다음과 같은 인터페이스를 확인할 수 있다.



4. 결론
node.js 로 네트워크 어플리케이션을 개발하는 것은 매우 쉽다. 아울러, 다양한 javascript 를 활용하여, 다양한 유저인터페이스를 구현할 수 있으며, 렌더링된 HTML은 스마트폰과 같은 다양한 장치에서 동일하게 보여지므로, N-Screen을 쉽게 구현할 수 있다.

참고로 Bluetooth 기반으로 개발하고자 한다면, 다음 링크를 참고한다.

댓글 1개:

  1. 안녕하세요 궁금한게 있어서 글 남깁니다.
    xbee(송신) 에서 전달받은 데이터를 xbee(수신)에서 받아 웹페이지에 출력하는 작업을 하고있습니다. 궁금한점은 위에서 말씀하신 부분에서 수신받는 xbee측과 웹서버간의 연결이 어떻게 이루어지는지 입니다.
    이더넷쉴드 없이 가능한가요 위에 작성하신 부분이?

    답글삭제