IOTOWN Manual

How to Send Data

1. 개요

IOTOWN에 데이터를 표현하기 위해서는 단말 장치에서 서버로 일정한 포맷의 데이터를 전송하여야 합니다. 전송의 방법 및 일부 포맷은 사용하는 무선, 유선 등 통신 방식의 종류에 따라 달라질 수 있습니다.

2. Data 표현 문법

2-1. JSON

JSON 객체처럼 "key":"value" 쌍으로 데이터를 표현하여 전송할 수 있습니다. 가령, 21도의 온도를 전송하기 위해서는 "temperature":21로 전송하면 됩니다. 전송하는 데이터의 첫번째 바이트는 반드시 " (double quote)여야 합니다. "key":"value" 쌍이 둘 이상이라면, , (comma)로 구분하면 됩니다. 가령, 위 온도와 함께 30%의 습도를 전송하기 위해서는 "temperature":21,"humidity":30으로 전송하면 됩니다. 만약, "key":"value" 쌍의 배열이 아니거나, 첫번째 바이트가 " (double quote)가 아닌 경우, 2-3. Raw의 방법으로 서버에서 처리됩니다.

2-2. 사용자 전용 포맷 (Biz only)

사용자 전용 포맷 방식은 새로운 프로젝트 용으로는 추천하지 않습니다. 가급적 Post Process 방식을 사용하는 것을 추천합니다.

사용자 전용의 포맷을 사용하기 위해서는 전송하는 데이터의 첫번째 바이트를 U (ASCII 코드 0x55) 로 설정하여야 합니다. 가령, 0x01, 0x02, 0x03, 0x04 의 4-byte 배열을 전송하기 위해서는 { 0x55, 0x01, 0x02, 0x03, 0x04 }로 전송하여야 합니다. 이렇게 전송된 데이터는 IOTOWN 내부의 사용자 전용 포맷 핸들러를 거쳐 JSON 객체로 변환하게 됩니다. 만약, 첫번째 바이트가 U (ASCII 코드 0x55)가 아닌 경우, 또는 사용자 전용 포맷 핸들러에서 변환이 불가능한 경우, 2-3. Raw의 방법으로 서버에서 처리됩니다.

이 기능은 IOTOWN-Biz에서만 지원합니다. 자세한 내용은 본사 기술지원으로 문의하시기 바랍니다.

사용자 전용 포맷 핸들러는 IOTOWN 설치경로의 configuration/iot.own/handler.js에서 찾을 수 있으며 다음과 같은 구조로 되어 있습니다.

exports.dataHandler = (data, node, gateway) => {
  let parsed = {};

  /* Please fill the user customized code here. */

  /*
    Return values
    - null: Invalid (or duplicate) data. Will be discarded.
    - object: Translated data
  */
  return parsed;
};
      

위 핸들러로 전달되는 파라미터는 다음과 같습니다.

{
  node_id: "String",
  node_type: "String",
  node_desc: "String",
  created_at: "Date",
  bootup_time: "Date",
  last_data: {
    ... /* 마지막으로 수신한 데이터 */
  },
  last_timestamp: "Date",
}
{
  group_id: "String",
  gateway_id: "String",
  gateway_type: "String",
  gateway_desc: "String",
  gateway_eui: "String",
  created_at: "Date",
  bootup_time: "Date",
  recent_act: "Date",
};

위 파라미터들을 이용하여 변환된 결과를 object 형태로 반환하면 됩니다. 변환된 object는 Dashboard 상의 데이터 시각화에 사용되고, DB에도 그대로 저장됩니다. 변환시 object의 key 이름은 자유롭게 사용이 가능하지만, 가급적 자동으로 추가되는 metadata의 key를 피해야 합니다. Metadata와 동일한 key 이름을 사용시 사용자가 지정한 값이 metadata의 값으로 덮어써질 수 있습니다.

만약, null을 반환하게 되면 IOTOWN은 해당 데이터를 버립니다. 가령, 마지막으로 수신했던 데이터(node.last_data) 등을 참고하여 중복된 데이터이거나 DB에 저장 및 Dashboard에 표현할 할 필요가 없는 데이터인 경우, null을 반환하게 하여 IOTOWN에서 더 이상의 처리를 막을 수 있습니다.

예를 들어, 첫번째 octet을 U로, 두번째 octet을 중복 방지용 sequence number로 하는 메시지 포맷을 사용한다면, 다음과 같이 중복 메시지를 거를 수 있습니다.

exports.dataHandler = (data, node, gateway) => {
  let lastData = Buffer.from(node.last_data.raw, 'base64');
  if (data[1] == lastData[1]) {
    /* Filter-out duplicate message */
    return null;
  }

  let parsed = {};

  /* Do something. */

  return parsed;
};

2-3. Raw

앞의 표현 문법에 어긋나 정상적인 데이터 표현이 불가능한 경우, 다음과 같이 IOTOWN에 표현 및 저장됩니다.

{
  "raw":base64 encoded raw data
};

위의 base64 encoded raw data는 IOTOWN에서 수신한 데이터의 base64 인코딩된 값을 의미합니다. 이 값은 라인 차트, 게이지 등 위젯 등으로 표현이 불가능하며, 사용자가 [GET] storage 등의 API를 통해 꺼내가서 base64 디코드 하여 사용할 수 있습니다.

3. LoRaWAN

LoRaWAN 단말장치는 우선 OTAA(Over-the-Air Actication)가 성공적으로 완료되어야 합니다. 이후 2. Data 표현 문법과 동일하게 IOTOWN으로 데이터를 전송하면 됩니다. Nol.A-SDK를 사용한 LoRaWAN 데이터 전송은 LoRaMac 클래스를 참고하시기 바랍니다. Confirmed 또는 unconfirmed 여부는 LoRaWAN 네트워크의 전송 제어와 관련된 부분으로 IOTOWN으로의 데이터 전송에는 상관이 없습니다. 그러나 unconfirmed 전송을 사용할 경우 데이터가 누락될 수 있으므로 주의하시기 바랍니다. 단, 포트번호는 1~222 (0x01~0xDE) 범위의 값이어야 합니다.

3-1. Meta-data

IOTOWN에서 LoRaWAN 프레임을 수신하면 다음과 같이 추가적인 메타데이터들이 함께 서버에 등록됩니다. 또한 Open API를 통한 callback으로도 전달됩니다.

{
  "key1": value1,
  "key2": value2,
  ...
  "raw": 수신한 데이터 (base64 encoded string),
  "fCnt": 수신한 프레임의 fCntUp 값 (integer),
  "fPort": 수신한 프레임의 port number (integer),
  "rssi": 수신한 프레임의 신호 세기(dB) (integer),
  "snr": 수신한 프레임의 Signal-to-Noise Ratio (float),
  "gateway" : [
    {
      "mac": 프레임을 수신한 게이트웨이의 EUI-64 (hexadecimal string, 예: '70B3D5DF10000001'),
      "rssi": 프레임의 수신 신호세기 (integer),
      "snr": 수신 프레임의 Signal-to-Noise Ratio (float)
    },
    ...
    {
      "mac": 프레임을 수신한 게이트웨이의 EUI-64 (hexadecimal string, 예: '70B3D5DF10000001'),
      "rssi": 프레임의 수신 신호세기 (integer),
      "snr": 수신 프레임의 Signal-to-Noise Ratio (float)
    }
  ],
  "freq": 사용된 채널(단위: Hz, integer),
  "mod": 사용된 변복조 방식('LoRa' 또는 'FSK', string),
  "bw": 사용된 대역폭(단위: kHz, integer),
  "sf": 사용된 Spreading Factor (LoRa only, integer),
  "cr": 사용된 Coding Rate (LoRa only, string),
  "adr": 송신한 장치에서의 ADR (adaptive data rate) 사용 여부 (boolean),
  "bps": 사용된 bitrate (FSK only, integer)
}

"key1":"value1", 및 "key2":"value2"는 사용자가 전송한 데이터를 의미합니다. rssi, 및 snr는 수신한 복수개의 게이트웨이들 중 가장 양호하게 수신한 게이트웨이의 값이 전달됩니다. 각 게이트웨이의 수신 신호를 알아보기 위해서는 gateway 배열을 참고하시기 바랍니다. gateway 배열은 신호가 양호한 순으로 정렬되어 전달됩니다. fCnt, fPort, adr 등 LoRaWAN 프로토콜과 관련된 항목들의 자세한 설명은 LoRaWAN Specification을 참고하시기 바랍니다.

4. MQTTs

TCP/IP 기반 단말장치는 MQTTs를 통해 IOTOWN으로 데이터를 전송할 수 있습니다.

MQTT는 데이터 전송시 평문이 그대로 노출되는 반면, MQTTs는 암호화가 이뤄집니다.
따라서, IOTOWN에서는 MQTTs만을 지원합니다.

4-1. Connect

MQTT로 데이터 전송을 하기 위해서는 먼저 IOTOWN과 단말간 접속이 이뤄져야 합니다. 접속에 필요한 파라미터는 다음과 같습니다.

4-2. Topics

IOTOWN에서 사용하는 publish 용 topics는 다음과 같습니다.

메시지 종류별 MQTT Topics
메시지 종류 Topic name
Device Boot iotown/tx/{Group ID}/device/{Device ID}/boot 또는
iotown/tx/{user name}/device/{Device ID}/boot
Device Data iotown/tx/{Group ID}/device/{Device ID}/data 또는
iotown/tx/{user name}/device/{Device ID}/data
  1. Group ID 확인은 사용자 정보에서 가능합니다.

정상적으로 접속이 완료된 후에는 Device Boot topic으로 메시지를 발생합니다. 내용은 비어있어도 상관이 없습니다.

이후 데이터를 전송할 때에는 Device Data topic으로 메시지를 발행합니다. 내용의 포맷은 Format을 참고합니다.

5. HTTPs

TCP/IP 기반 단말장치는 HTTPs 기반 RESTful API를 통해 IOTOWN으로 데이터를 전송할 수 있습니다.

HTTPs 방식은 한번 데이터 전송을 위해서 TCP 연결을 맺고 끊는 절차를 반복하므로 MQTTs에 비해 오버헤드가 심합니다.
가급적 MQTTs 방식을 추천합니다.

5-1. Post

데이터 전송을 위한 API는 [POST] data 입니다. 자세한 내용은 해당 문서를 참고하세요.