Node.js & MQTT를 이용한 센싱 데이터 전송

zzzzini·2023년 7월 26일
0

Node.js & MQTT

목록 보기
2/2
post-thumbnail

이번 포스트에서는 Node.js 환경에서 MQTT를 사용해 센싱 데이터를 주고받는 방법에 대해 제가 실습해본 내용을 바탕으로 소개할 예정입니다.

✅ 실습 환경

두개의 visual studio code 프로젝트 MQTT_T1, MQTT_T2를 실행한 뒤,
두 프로젝트에 각각 main.js 파일을 생성합니다.

⚙️ nodemon 세팅

nodemon은 파일 변경을 감지하면, 자동으로 서버를 재시동하여 수정 사항을 서버에 적용시켜주는 편리한 도구입니다.

npm install nodemon

두 프로젝트 모두 터미널에 위 명령어를 입력하여 nodemon 패키지를 설치해줍니다.

npm install -g nodemon

위 코드로 설치하는게 국룰같은데, 전 새로운 프로젝트들에 대해선 해당 명령어가 먹지 않아서 -g는 제외하였습니다.

nodemon 설치가 완료되었다면 터미널에 다음 명령어를 입력합니다.

npm init -y

그러면 package.json 파일이 프로젝트 폴더 내에 생성되는데,
package.json 파일에 들어가 "scripts"에 다음 코드를 작성합니다.

"server": "nodemon main.js"

npm run server

이처럼 세팅을 해주면, 터미널에 간편하게 위 명령어를 입력하는 것으로 서버를 구동시킬 수 있습니다.

서버 종료를 원할땐 터미널을 선택한 뒤 ctrl + c를 통해 종료할 수 있습니다.

두 프로젝트 모두 기본적으로 서버 세팅이 완료되면, 코드를 작성합니다.

📄 [MQTT_T1] main.js 작성

MQTT_T1의 main.js는 센싱 데이터를 수집하여 메시지를 발행하는 역할을 수행합니다.

📦 패키지 불러오기

위 예제에서는 express, http, mqtt, serialport 패키지를 사용하였습니다.

npm install express
npm install http
npm install mqtt
npm install serialport

이후 패키지들을 다음처럼 불러와 사용합니다.

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const mqtt = require('mqtt');
const { SerialPort, ReadlineParser } = require('serialport');

필요에 따라 MQTT 사용을 위해 mosquitto 브로커 설치가 필요할 수 있습니다.
https://pros2.tistory.com/137
위 블로그를 참고하시면 될 것 같습니다.

🚨 SerialPort 객체 생성하기

다음으로, Uno보드와 연결 설정을 위해 SerialPort 객체 생성 및 parser를 연결해줍니다.

var port = new SerialPort({
  path : '연결된 우노보드 경로',
  baudRate : 9600,
  autoOpen : false
});

const parser = port.pipe(new ReadlineParser());

연결된 우노 보드 경로는 아두이노 IDE 에서 포트 경로로 찾을 수 있습니다.

이번 실습은 우노 보드 하나에 sound 센서 2개를 연결하는 방식으로 진행하였습니다.

보드에 센서는 사진과 같이 연결하였습니다.

보드에 업로드한 코드는 아래와 같습니다.

int Sensor1value = 0;
int Sensor2value = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  Sensorread();
  delay(1000);
}

void Sensorread(){     
  Sensor1value = analogRead(0);  
  Sensor2value = analogRead(1);
  
  Serial.print(Sensor1value);
  Serial.print(",");
  Serial.print(Sensor2value);
  Serial.print(",");
  Serial.print(Sensor1value);
  Serial.print(",");
  Serial.print(Sensor2value);
  Serial.print(",");
  Serial.print(Sensor1value);
  Serial.print(",");
  Serial.println(Sensor2value);
}

보드에 위 코드를 업로드시킨 후에 진행하면 됩니다.

📝 센싱 데이터를 메시지로 발행하기

아래 코드를 이어서 작성하면 우노 보드를 통해 전달된 센싱 데이터들이 메시지에 담겨 발행되게 됩니다.

port.open(function(error) {
  if (error) {
    console.log("연결된 포트 없음");
  } else {
    console.log("시리얼 포트 연결됨");
  
    // MQTT 브로커에 연결합니다.
    const client = mqtt.connect('mqtt://test.mosquitto.org');
  
    client.on('connect', function () {
      console.log('MQTT 클라이언트 연결됨');
  
      // 센싱 데이터를 MQTT 브로커로 전송
      parser.on('data', function (data) {
        var datetime = new Date()
        var year = datetime.getFullYear();
        var month = datetime.getMonth() + 1;
        var day = datetime.getDate();
        var hours = datetime.getHours();
        var minutes = datetime.getMinutes();
        var seconds = datetime.getSeconds();

        var timestamp = year + '-' + num_2(month) + '-' + num_2(day) + ' ' + num_2(hours) + ':' + num_2(minutes) + ':' + num_2(seconds);

        // timestamp를 xxxx년 xx월 xx일 xx시 xx분 xx초 형식으로 변환
        function num_2(num) {
          return (num < 10 ? '0' : '') + num;
        }

        var values = data.trim().split(',');
  
        var senddata = {
          timestamp: timestamp,
          value1: values[0],
          value2: values[1],
          value3: values[2],
          value4: values[3],
          value5: values[4],
          value6: values[5]
        };
  
        // 데이터를 JSON으로 변환하여 'data'로 전송
        client.publish('data', JSON.stringify(senddata));
        console.log("전송된 데이터:", senddata);
      });
    });
  }
})

작성자가 많이 부족하여 실습에 사용한 코드가 다소 주먹구구식인 점 양해 부탁드립니다.

코드를 작성 완료한 뒤에 MQTT_T1 프로젝트에서 npm run server 명령어를 통해 서버를 작동시키면, 모든 연결이 정상적으로 수행되었다는 전제 하에 센싱 데이터가 메시지로 발행되게 됩니다.

📄 [MQTT_T2] main.js 작성

MQTT_T2의 main.js는 MQTT_T1의 main.js에서 발행된 메시지를 구독하고, 이를 출력해주는 단순한 기능을 수행합니다.

📦 패키지 불러오기

구독 기능만 수행하면 되므로, 단순히 mqtt 패키지만 설치합니다.

npm install mqtt

이후 패키지를 다음처럼 불러와 사용합니다.

const mqtt = require("mqtt");

const client = mqtt.connect('mqtt://test.mosquitto.org');

📝 메시지 구독 및 출력하기

메시지를 구독하여 출력만 하면 되므로, 코드가 매우 간단해집니다.

client.on('connect', function() {
  console.log('MQTT 클라이언트 연결됨');
})

client.subscribe('data');
client.on('message', function(topic, message) {
  message = JSON.parse(message);
  var timestamp = message.timestamp;
  var value1 = message.value1;
  var value2 = message.value2;
  var value3 = message.value3;
  var value4 = message.value4;
  var value5 = message.value5;
  var value6 = message.value6;
  console.log("Received : [" + timestamp + ", " + value1 + ", " + value2 + ", " + value3 + ", " + value4 + ", " + value5 + ", " + value6 + "]");
}) 

마찬가지로 작성자가 많이 부족하여 실습에 사용한 코드가 다소 주먹구구식인 점 양해 부탁드립니다.

코드를 작성 완료한 뒤에 MQTT_T2 프로젝트에서 npm run server 명령어를 통해 서버를 작동시키면, MQTT_T1 프로젝트에서 발행되는 메시지를 받아와 출력하는 기능을 수행하게 됩니다.

📺 실습 화면

영상에서처럼 실시간 센싱 데이터들이 메시지로 발행되고, 이를 구독받아 획득하는 과정이 잘 진행됩니다.

📌 마치며..

비록 많이 허술한 코드들이지만.. 그냥 이런 방법이 있다는 정도로 참고해주시면 감사하겠습니다.

node.js로 센싱 데이터를 MQTT를 통해 주고 받으실 때 유용하게 사용하셨으면 좋겠습니다.

둥글둥글한 훈수는 언제나 대환영입니다.

profile
소프트웨어전공 조난자

0개의 댓글