Developer Documentation v1.0
고감도 DDIA(Data-Driven Interior Analytics) 시스템과 연동하기 위한 센서 하드웨어 통합 API 문서입니다. 재실 센서, 환경 센서 등 다양한 IoT 디바이스에서 실시간 데이터를 전송할 수 있습니다.
관리자 대시보드에서 프로젝트별 API 키를 생성합니다.
센서 디바이스에 API 키와 엔드포인트 URL을 설정합니다.
센서에서 이벤트/데이터를 REST API로 전송합니다.
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 섹션에서 프로젝트별로 생성할 수 있습니다.
Authorization: Bearer sk_live_abc123def456.../api/sensor/status현재 API 키의 상태와 사용량을 확인합니다.
{
"success": true,
"projectId": 1,
"keyName": "3층 센서 허브",
"requestCount": 15420,
"active": true,
"serverTime": "2026-02-16T09:00:00.000Z"
}재실 센서에서 사람의 출입 이벤트를 전송합니다. 이 데이터는 공간 활용 히트맵, 동선 분석, 체류 시간 분석에 활용됩니다.
/api/sensor/event단건 재실 이벤트를 전송합니다.
{
"sensorId": "sensor-001", // (필수) 센서 고유 ID
"eventType": "enter", // (필수) "enter" | "exit" | "count_change"
"zoneId": 5, // (선택) 구역 ID (미지정 시 자동 매핑)
"count": 1, // (선택) 인원 수 변화량
"eventAt": 1708000000000, // (선택) 이벤트 발생 시각 (Unix ms, 미지정 시 서버 시각)
"deviceId": "hub-3f" // (선택) 게이트웨이/허브 ID
}{
"success": true,
"message": "Event recorded"
}/api/sensor/events/batch여러 재실 이벤트를 한 번에 전송합니다. 최대 1,000건까지 지원합니다.
{
"events": [
{
"sensorId": "sensor-001",
"eventType": "enter",
"count": 1,
"eventAt": 1708000000000
},
{
"sensorId": "sensor-002",
"eventType": "exit",
"count": -1,
"eventAt": 1708000001000
}
]
}{
"success": true,
"message": "2 events recorded",
"count": 2
}실제 API 키를 입력하고 요청을 보내 결과를 확인할 수 있습니다.
관리자 대시보드 → DDIA → API 키 관리에서 발급받은 키를 입력하세요.
/api/sensor/eventimport 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"}#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();
}
}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);