2015년 9월 2일 수요일

node.js 기반 홈 오토메이션 서버 개발

아두이노와 라즈베리파이 기반으로 오토메이션 서버를 개발해 본다.

1. 개요
오토메이션 서버는 다음과 같은 기능을 가진다.
1) 온도 등 환경 센서를 취득해, 인터넷상으로 정보를 표현
2) 램프 등 주변장치를 인터넷상으로 켜고 끌 수 있음
3) Bluetooth로 접근할 수 있음
4) ProcessingJS로 그래픽 처리

2. 준비물
1) 온도, 습도, 광센서, 전류측정센서 및 아두이노 우노 보드
2) node.js 등 라이브러리 (이전 글 참고)
3) 릴레이 및 램프


3. 개발
이를 개발하기 위해, 온도, 습도, 광 센서 등이 필요하다.

1) 아두이노 코딩
// Code to measure data & make it accessible via 

// Libraries
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include <aREST.h>

// DHT sensor
#define DHTPIN 7 
#define DHTTYPE DHT11

// LCD display instance
LiquidCrystal_I2C lcd(0x27,20,4); 

// DHT instance
DHT dht(DHTPIN, DHTTYPE);

// Create aREST instance
aREST rest = aREST();

// Variables to be exposed to the API
int temperature;
int humidity;
int light;

void setup()
{
  // Start Serial
  Serial.begin(115200);
  
  // Expose variables to REST API
  rest.variable("temperature",&temperature);
  rest.variable("humidity",&humidity);
  rest.variable("light",&light);
  
  // Set device name & ID
  rest.set_id("1");
  rest.set_name("weather_station");
  
  // Initialize the lcd 
  lcd.init();
  
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(1,0);
  lcd.print("Hello !");
  lcd.setCursor(1,1);
  lcd.print("Initializing ...");
  
  // Init DHT
  dht.begin();
  
  // Clear LCD
  lcd.clear();
}


void loop()
{
  
  // Measure from DHT
  temperature = (int)dht.readTemperature();
  humidity = (int)dht.readHumidity();
  
  // Measure light level
  float sensor_reading = analogRead(A0);
  light = (int)(sensor_reading/1024*100);
  
  // Handle REST calls
  rest.handle(Serial);
  
  // Display temperature
  lcd.setCursor(1,0);
  lcd.print("Temperature: ");
  lcd.print((int)temperature);
  lcd.print((char)223);
  lcd.print("C");
  
   // Display humidity
  lcd.setCursor(1,1);
  lcd.print("Humidity: ");
  lcd.print(humidity);
  lcd.print("%");
  
   // Display light level
  lcd.setCursor(1,2);
  lcd.print("Light: ");
  lcd.print(light);
  lcd.print("%");
  
  // Wait 100 ms
  delay(100);
}

2) 서버 node.js 코딩
// Modules
var express = require('express');
var app = express();

// Define port
var port = 3000;

// View engine
app.set('view engine', 'jade');

// Set public folder
app.use(express.static(__dirname + '/public'));

// Rest
var rest = require("arest")(app);
rest.addDevice('serial','/dev/tty.usbmodem1a12121', 115200);

// Serve interface
app.get('/', function(req, res){
  res.render('interface');
});

// Start server
app.listen(port);
console.log("Listening on port " + port);


// interface.js
var devices = [];

$.get('/devices', function( json_data ) {
  devices = json_data;
});

$(document).ready(function() {

  function updateSensors() {
    
    // Update light level and status
    $.get('/' + devices[0].name + '/light', function(json_data) {

      console.log(json_data.light);

      $("#lightDisplay").html("Light level: " + json_data.light + "%");    

      // Update status
      if (json_data.connected == 1){
        $("#status").html("Station Online");
        $("#status").css("color","green");    
      }
      else {
        $("#status").html("Station Offline");
        $("#status").css("color","red");     
      }

      $.get('/' + devices[0].name + '/temperature', function(json_data) {
        $("#temperatureDisplay").html("Temperature: " + json_data.temperature + "°C");
        
        $.get('/' + devices[0].name + '/humidity', function(json_data) {
          $("#humidityDisplay").html("Humidity: " + json_data.humidity + "%");
        });
      });
    });
  }

  setTimeout(updateSensors, 500);
  setInterval(updateSensors, 5000);


});


댓글 없음:

댓글 쓰기