RADAR 설정하러 가기 👉

SEUNGHWANLEE·2021년 2월 14일
0

Mobius Guideline

목록 보기
8/11

본 Radar(레이더)는 동국대학교 TEstBEd에서 제공해준 (주)탑엔지니어링, SMART Radar Sensor 입니다.


RADAR의 역할은 하나의 TAS, 일종의 액추에이터 기능으로 사용하였습니다. 따라서 간단한 서버가 필요합니다. 해당 소스코드는 제 개인 깃허브에 업로드 해두었습니다. 그럼 먼저 소스코드에 대한 설명을 하겠습니다. 😁

RADAR(레이더)에서 송신하는 데이터를 받아줄 SERVER(서버)를 만들어 줍니다. 이때 RADAR(레이더)는 CLIENT(클라이언트) 역할을 수행합니다.

net.Socket으로 Server 만들기

tas_radar로 tas_sample 디렉토리안에 새롭게 생성해주었습니다. tas_radar는 아래와 같은 package.json으로 구성되있으니 참고하시면 되겠습니다.

{
  "name": "tas-radar",
  "version": "1.0.0",
  "description": "tas-radar",
  "engines": {
    "node": "10.15.0",
    "npm": "6.9.0"
  },
  "scripts": {
    "start": "nodemon index.js"
  },
  "author": "Seunghwan Lee",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^8.2.0",
    "ip": "^1.1.5",
    "mysql": "^2.18.1"
  }
}
tas_radar
└───node_modules
│   .env
│   index.js
│   data_parse.js
│   package.json
│   package-lock.json

기능 구현을 위해서 간단하게 두개의 함수를 만들었습니다. tasReady와 tasHandler인데, tasReady에서 레이더에서 송신하는 데이터를 받고, 수신된 데이터가 있는 경우에 tasHandler가 작동됩니다. 코드는 다음과 같습니다.

1) .env

레이더가 송신할 포트는 겹치지만 않도록 설정해주시면 됩니다. 앞서 thyme에서 tasport가 3105로 설정이 되어있기 때문에 .env 파일은 아래와 같이 설정하였습니다.

RS_PORT=3333
ST_PORT=3105

index.js 와 같은 디렉토리에 저장해주시면 되고, 저는 3333으로 포트를 설정해주었습니다. 😁

2) tasReady

const tasReady = () => {
    if (_server === null) {
        // create server
        _server = new net.createServer((socket) => {
            console.log('[ socket connected ]');
            // ...
        })
        _server.listen(process.env.RS_PORT, () => console.info('TCP SERVER listening on :' + ip.address() + ":" + port.toString()));
    }
}

_server 라는 전역변수가 있으며 null 값으로 초기화가 되어있습니다. net.createServer를 통해서 서버 객체를 생성해주고 listen을 통해 접속하려는 클라이언트가 설정된 포트(port)로 접속할 수 있도록 동작을 시킵니다. net.createServer 함수 안에는 callback 함수가 있어서 클라이언트가 요청을 하면 callback 함수가 작동됩니다.

net.createServer의 callback 함수

callback 함수를 이용하여 다양한 기능을 구현할 수 있습니다. 이번에는 가장 기본적인 4개를 이용하여 구현을 해보았습니다.

...
    // to thyme
    var net = require('net');
    var asClient = net.connect({ port: process.env.ST_PORT });

    // socket encoding
    socket.setEncoding('hex');

    // data
    socket.on('data', (data) => tasHandler(data, asClient));
    // end
    socket.on('end', (data) => console.log('[ socket end with data : ' + data + ']'));
    // close
    socket.on('close', (hasErr) => hasErr ? console.error('[ socket closed with error ]') : console.info('[ socket closed ]'));
    // error
    socket.on('error', (err) => console.error('**ERROR**\n>> : ' + err));
...
  1. to thyme

       // to thyme
        var net = require('net');
        var asClient = net.connect({ port: process.env.ST_PORT });

    net을 다시 이용해서 RADAR에서 받은 데이더를 Thyme로 전송하기 위해 연결할 포트를 설정해줍니다.

RADAR(레이더) : CLIENT(클라이언트) —————> RS_PORT : SERVER(서버)
RS_PORT : CLIENT(클라이언트) —————> ST_PORT : SERVER(서버)

[참고] 여기서 RS_PORT는 Radar-to-Server이며, ST_PORT는 Server-to-Thyme 입니다. 
  1. encoding

    레이더에서 송신하는 값이 16진수로 구성이 되어있어서 hex로 인코딩해주었습니다.

  2. data

    클라이언트로 부터 오는 데이터를 처리해주는 함수입니다. 여기서 데이터와 서버가 다시 클라이언트 역할을 수행하므로 그 역할을 해줄 asClient를 파라미터로 data와 함께 tasHandler에게 전달합니다.

  3. end

    클라이언트로 부터 오는 데이터가 끝났을때 처리해주는 함수입니다. 로그를 출력해줍니다.

  4. close

    클라이언트와 접속이 끊어지는 경우 처리해주는 함수입니다. close 함수는 hasErr, 즉 에러 발생 유무를 반환해주기 때문에 콜백함수로 에러와 함께 종료됐는지 확인할 수 있습니다. 상황에 맞는 로그를 출력해줍니다.

  5. error

    클라이언트와 접속에서 오류가 발생했을 때 처리해주는 함수입니다. 로그를 출력해줍니다.

3) tasHandler

const tasHandler = (data, client) => {
    // parseRadarData(data);

    if (data === null) {
        // socket keep alive only for data is null !
        client.setKeepAlive(true, 5000);
    }
    // send to thyme
    client.on('connect', () => {
        // data -> trash
        if (data.toString().substring(0, 4) !== 'ffff') {
            // not working with parsed data ...
            // var send = JSON.stringify(parseRadarData(data)).replace(/"([^"]+)":/g, '$1:');
            // client.write(JSON.stringify(cin).replace(/\\"/g, "'") + '<EOF>');
                        
            var cin = { ctname: 'radar', con: data };
            
            client.write(JSON.stringify(cin) + '<EOF>');
        }
    });
    client.on('error', (err) => console.error(err));
    client.on('close', () => client.destroy());
}

위에서 클라이언트가 데이터를 송신 했을 경우 작동되는 함수입니다. datanull 인 경우에는 client가 계속 좀비커넥션을 방지하기 위해서 setKeepAlive를 사용하였습니다.

앞서 tasReady에서 설정한 port로 성공적으로 연결이 된다면, client.on('connect', callback)이 실행됩니다. callback함수안에서는 레이더로부터 수신한 데이터가 잘못된 값인지를 판별하기 위해서 if문을 걸어두었습니다. 잘못된 값이 아닌 경우, thyme가 mobius에게 전송하는 형식에 맞춰서 write를 해줍니다. 나머지는 error가 발생하거나 close될 때 callback함수를 설정해주었습니다.


⚠️ 현재 mobius에서 제가 만든 json 구조가 내장되어있는 함수에 올바르지 않은 format인지 모르겠으나 json구조를 JSON.stringify()하여 nCube 포트 3105로 전송을 하게되면 parsing error가 발생합니다. 데이터에서 송신한 16진수의 모음으로 이루어진 String 값을 그대로 3105 port로 전송하면 성공적으로 callback함수가 작동하여, 우선 parsing error가 발생하지 않는 String 값으로 코드를 작성하였습니다. 위 코드를 실행하시면 아래 화면처럼 데이터가 쌓이는 것을 확인할 수 있습니다.


MySQL Workbench에서 확인한 모습


RADAR 기본설정하기

레이더 설정하러가기 👉

⚠️ 간혹 레이더가 스스로 AP를 바꾸는 경우, 다시 AP를 설정해주어야합니다.😅

Grafana로 데이터 들어오는 것 확인하기 👉

profile
잡동사니 😁

1개의 댓글

comment-user-thumbnail
2023년 3월 30일

안녕하세요 docker에서 실행하는 서버랑 Host의 mysql workbench를 연결하려고 Host:localhost, Port:8080으로 진행하였는데 MySQL workbench에서
Lost connection to MySQL server at 'reading initial communication packet', system error: 10060
에러가 발생하였습니다. docker의 sql이랑 Host의 workbench를 어떻게 연결하면 좋을까요?

답글 달기