홈으로 돌아가기

고감도 센서 연동 API

Developer Documentation v1.0

고감도 DDIA(Data-Driven Interior Analytics) 시스템과 연동하기 위한 센서 하드웨어 통합 API 문서입니다. 재실 센서, 환경 센서 등 다양한 IoT 디바이스에서 실시간 데이터를 전송할 수 있습니다.

REST APIJSONBearer Auth
빠른 시작 가이드
1

API 키 발급

관리자 대시보드에서 프로젝트별 API 키를 생성합니다.

2

센서 설정

센서 디바이스에 API 키와 엔드포인트 URL을 설정합니다.

3

데이터 전송

센서에서 이벤트/데이터를 REST API로 전송합니다.

빠른 테스트 (cURL)
bash
curl -X POST \
  https://your-domain.com/api/sensor/event \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sensorId": "sensor-001",
    "eventType": "enter",
    "count": 1
  }'

모든 API 요청에는 Authorization 헤더에 Bearer 토큰 형식으로 API 키를 포함해야 합니다. API 키는 관리자 대시보드의 DDIA 섹션에서 프로젝트별로 생성할 수 있습니다.

인증 헤더 형식
HTTP
Authorization: Bearer sk_live_abc123def456...

보안 주의사항

  • API 키는 생성 시 한 번만 표시됩니다. 안전한 곳에 보관하세요.
  • API 키를 소스 코드에 하드코딩하지 마세요. 환경 변수를 사용하세요.
  • 키가 노출된 경우 즉시 관리자 대시보드에서 폐기하고 새 키를 발급받으세요.
  • 각 API 키는 특정 프로젝트에 바인딩됩니다.

API 키 상태 확인

GET/api/sensor/status

현재 API 키의 상태와 사용량을 확인합니다.

Response
JSON
{
  "success": true,
  "projectId": 1,
  "keyName": "3층 센서 허브",
  "requestCount": 15420,
  "active": true,
  "serverTime": "2026-02-16T09:00:00.000Z"
}

재실 센서에서 사람의 출입 이벤트를 전송합니다. 이 데이터는 공간 활용 히트맵, 동선 분석, 체류 시간 분석에 활용됩니다.

POST/api/sensor/event

단건 재실 이벤트를 전송합니다.

Request Body
JSON
{
  "sensorId": "sensor-001",      // (필수) 센서 고유 ID
  "eventType": "enter",          // (필수) "enter" | "exit" | "count_change"
  "zoneId": 5,                   // (선택) 구역 ID (미지정 시 자동 매핑)
  "count": 1,                    // (선택) 인원 수 변화량
  "eventAt": 1708000000000,      // (선택) 이벤트 발생 시각 (Unix ms, 미지정 시 서버 시각)
  "deviceId": "hub-3f"           // (선택) 게이트웨이/허브 ID
}
Response
JSON
{
  "success": true,
  "message": "Event recorded"
}
eventType 필드는 enter(입장), exit(퇴장), count_change(인원 변동) 중 하나여야 합니다. count를 지정하지 않으면 enter=+1, exit=-1, count_change=0으로 자동 설정됩니다.
POST/api/sensor/events/batch

여러 재실 이벤트를 한 번에 전송합니다. 최대 1,000건까지 지원합니다.

Request Body
JSON
{
  "events": [
    {
      "sensorId": "sensor-001",
      "eventType": "enter",
      "count": 1,
      "eventAt": 1708000000000
    },
    {
      "sensorId": "sensor-002",
      "eventType": "exit",
      "count": -1,
      "eventAt": 1708000001000
    }
  ]
}
Response
JSON
{
  "success": true,
  "message": "2 events recorded",
  "count": 2
}
배치 전송은 네트워크 효율성을 높이기 위해 권장됩니다. 한 번에 최대 1,000건까지 전송할 수 있습니다.
API 테스트 (Try it out)

실제 API 키를 입력하고 요청을 보내 결과를 확인할 수 있습니다.

관리자 대시보드 → DDIA → API 키 관리에서 발급받은 키를 입력하세요.

POST/api/sensor/event
연동 코드 예제
Python 예제
Python
import requests
import time

API_KEY = "sk_live_your_api_key_here"
BASE_URL = "https://your-domain.com/api/sensor"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# 단건 이벤트 전송
def send_event(sensor_id, event_type, count=None):
    payload = {
        "sensorId": sensor_id,
        "eventType": event_type,
        "eventAt": int(time.time() * 1000)
    }
    if count is not None:
        payload["count"] = count
    
    response = requests.post(
        f"{BASE_URL}/event",
        json=payload,
        headers=HEADERS
    )
    return response.json()

# 배치 이벤트 전송
def send_batch_events(events):
    response = requests.post(
        f"{BASE_URL}/events/batch",
        json={"events": events},
        headers=HEADERS
    )
    return response.json()

# 하트비트 전송
def send_heartbeat(sensor_id, battery=None):
    payload = {"sensorId": sensor_id, "status": "online"}
    if battery is not None:
        payload["battery"] = battery
    
    response = requests.post(
        f"{BASE_URL}/heartbeat",
        json=payload,
        headers=HEADERS
    )
    return response.json()

# 사용 예시
result = send_event("sensor-001", "enter", count=1)
print(result)  # {"success": true, "message": "Event recorded"}
Arduino / ESP32 예제
C++
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

const char* API_KEY = "sk_live_your_api_key_here";
const char* BASE_URL = "https://your-domain.com/api/sensor";
const char* SENSOR_ID = "sensor-esp32-001";

void sendOccupancyEvent(const char* eventType, int count) {
  HTTPClient http;
  String url = String(BASE_URL) + "/event";
  
  http.begin(url);
  http.addHeader("Authorization", String("Bearer ") + API_KEY);
  http.addHeader("Content-Type", "application/json");
  
  StaticJsonDocument<256> doc;
  doc["sensorId"] = SENSOR_ID;
  doc["eventType"] = eventType;
  doc["count"] = count;
  doc["eventAt"] = millis();  // 실제로는 NTP 시각 사용 권장
  
  String payload;
  serializeJson(doc, payload);
  
  int httpCode = http.POST(payload);
  if (httpCode == 200) {
    Serial.println("Event sent successfully");
  } else {
    Serial.printf("Error: %d\n", httpCode);
  }
  http.end();
}

void sendHeartbeat(int battery, int rssi) {
  HTTPClient http;
  String url = String(BASE_URL) + "/heartbeat";
  
  http.begin(url);
  http.addHeader("Authorization", String("Bearer ") + API_KEY);
  http.addHeader("Content-Type", "application/json");
  
  StaticJsonDocument<256> doc;
  doc["sensorId"] = SENSOR_ID;
  doc["status"] = "online";
  doc["battery"] = battery;
  doc["rssi"] = rssi;
  doc["firmware"] = "v1.0.0";
  
  String payload;
  serializeJson(doc, payload);
  http.POST(payload);
  http.end();
}

void setup() {
  Serial.begin(115200);
  // WiFi 연결 코드...
}

void loop() {
  // PIR 센서 감지 시 이벤트 전송
  if (digitalRead(PIR_PIN) == HIGH) {
    sendOccupancyEvent("enter", 1);
    delay(5000);  // 디바운스
  }
  
  // 10분마다 하트비트 전송
  static unsigned long lastHeartbeat = 0;
  if (millis() - lastHeartbeat > 600000) {
    sendHeartbeat(analogRead(BATTERY_PIN), WiFi.RSSI());
    lastHeartbeat = millis();
  }
}
Node.js 예제
JavaScript
const API_KEY = process.env.SENSOR_API_KEY;
const BASE_URL = "https://your-domain.com/api/sensor";

async function sendEvent(sensorId, eventType, count) {
  const response = await fetch(`${BASE_URL}/event`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      sensorId,
      eventType,
      count,
      eventAt: Date.now()
    })
  });
  return response.json();
}

async function sendBatchEvents(events) {
  const response = await fetch(`${BASE_URL}/events/batch`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ events })
  });
  return response.json();
}

// 사용 예시
const result = await sendEvent("sensor-001", "enter", 1);
console.log(result);
제한 사항 및 모범 사례

전송 제한

  • 배치 전송: 요청당 최대 1,000건
  • 요청 본문 크기: 최대 1MB
  • 타임스탬프: Unix 밀리초 형식 (UTC 기준)

모범 사례

  • 가능하면 배치 전송을 사용하여 네트워크 효율성을 높이세요
  • 네트워크 장애 시 로컬 버퍼링 후 복구 시 배치 전송
  • 하트비트를 5~15분 간격으로 전송하여 센서 상태 모니터링
  • 센서 ID는 프로젝트 내에서 고유하게 유지하세요

기술 지원이 필요하신가요?

센서 연동 관련 기술 문의는 고감도 담당자에게 연락해주세요.