Coming soon

서비스를 준비 중입니다

지금은 마지막 손질을 하고 있어요. 준비가 끝나면 이 버튼에서 바로 이어드릴게요.

그동안 사용 설명서 둘러보기 →

센서 연결

나만의 센서 데이터를 Open API로 전송하기

API Key를 사용하여 외부 센서 데이터를 내정원의 사계절로 전송하는 방법입니다.

마지막 수정

라즈베리파이나 아두이노로 직접 만든 센서, 또는 이미 사용 중인 다른 시스템의 측정값을 Open API로 내정원의 사계절에 보낼 수 있습니다. 전송된 값은 Ecowitt 센서와 똑같이 구역·식물에 연결해 사용할 수 있습니다.

앱에서 API 키 발급 → 서명 생성 → 측정값 전송 → 센서 등록 확인 → 구역·식물 연결

시작하기 전에

확인 항목 준비 상태
장소 API 키는 장소에 속하므로 장소가 하나 이상 있어야 합니다.
전송 프로그램 HTTPS 요청과 HMAC-SHA256 계산이 가능해야 합니다.
시각 동기화 보내는 기기의 시계가 실제 시각과 맞아야 합니다.

서명에 현재 시각이 들어가고 서버가 5분 이내인지 검사하므로, 기기 시계가 틀어져 있으면 모든 요청이 거부됩니다. NTP 동기화를 먼저 확인해 주세요.


1. API 키 발급

앱에서 다음 순서로 이동합니다.

MY → 설정 → 센서 관리 → 오른쪽 위 + 버튼

OpenAPI를 선택하고 Key 이름을 입력한 뒤 저장합니다. 키 이름은 여러 키를 구분하기 위한 이름으로, 베란다 파이처럼 알아보기 쉽게 지으면 됩니다.

발급되는 값은 두 가지입니다.

값 용도
Access Key 요청을 보낼 때 신원을 밝히는 공개 값
Secret Key 서명을 만드는 데 쓰는 비밀 값

Secret Key는 발급 시점에 한 번만 제공됩니다. 저장 화면이 뜨면 CSV 파일을 반드시 저장해 두세요. 잃어버리면 다시 확인할 수 없고 키를 새로 발급해야 합니다.

발급 제한

종류 등록 가능 개수
OpenAPI 키 2개
Ecowitt 키 1개

ecowitt는 예약된 이름이라 Key 이름으로 사용할 수 없습니다.


2. 엔드포인트

항목 값
URL https://collector.seasonsingarden.life/api/sensor/v1/data
메서드 POST
Content-Type application/json

반드시 https로 보내야 합니다. http로 요청하면 301 리다이렉트가 반환되고, 대부분의 클라이언트는 리다이렉트 과정에서 본문이나 메서드를 잃습니다.


3. 인증 서명 만들기

모든 요청에는 아래 세 개의 헤더가 필요합니다.

헤더 값
X-API-Key 발급받은 Access Key
X-Timestamp 현재 시각의 epoch 밀리초
X-Signature 아래 규칙으로 만든 서명

서명 문자열

다음 세 줄을 줄바꿈(\n)으로 이어 붙입니다. 마지막에 줄바꿈을 넣지 않습니다.

POST /api/sensor/v1/data
1757232000000
발급받은_Access_Key
줄 내용
1번째 HTTP 메서드, 공백 한 칸, 요청 경로
2번째 X-Timestamp와 같은 값
3번째 Access Key

이 문자열을 Secret Key로 HMAC-SHA256 해시한 뒤 Base64로 인코딩한 값이 X-Signature입니다.

유효 시간

조건 결과
서버 시각과 5분 이내 통과
5분 초과 거부
서버 시각보다 미래 거부

요청마다 새 timestamp로 서명을 다시 만들어야 합니다. 서명은 재사용할 수 없습니다.


4. 요청 본문

{
  "device_name": "베란다 파이",
  "date": "2026-09-07 08:00:00",
  "sensors": [
    {
      "field_nm": "temp1",
      "field_kor_nm": "베란다 온도",
      "category": "01",
      "unit": "°C",
      "data": "23.5"
    },
    {
      "field_nm": "soil1",
      "field_kor_nm": "화분 토양습도",
      "category": "07",
      "unit": "%",
      "data": "42"
    }
  ]
}
필드 필수 설명
device_name 선택 보내는 기기의 이름
date 필수 측정 시각. UTC 기준 yyyy-MM-dd HH:mm:ss
sensors 필수 측정값 배열. 한 번에 여러 센서를 보낼 수 있습니다.
sensors[].field_nm 필수 센서를 구분하는 고유 이름
sensors[].field_kor_nm 선택 사람이 읽을 이름. 현재 서버는 이 값을 저장하지 않고 field_nm을 표시 이름으로 씁니다.
sensors[].category 필수 측정 항목 코드 (아래 표)
sensors[].unit 선택 단위
sensors[].data 필수 측정값. 문자열로 보냅니다.

date는 한국 시간이 아니라 UTC입니다. 한국 시간 오후 5시는 2026-09-07 08:00:00으로 보냅니다. 이 값을 기준으로 일별 최고·최저값이 계산되므로 시간대를 틀리면 그래프가 어긋납니다.

field_nm 정하기

field_nm은 센서를 식별하는 값입니다. 처음 보는 field_nm이 들어오면 새 센서가 자동으로 등록되고, 이후 같은 이름으로 보낸 값이 그 센서에 쌓입니다.

한번 정한 뒤에는 바꾸지 마세요. 이름을 바꾸면 별개의 센서가 새로 생기고 기존 기록과 이어지지 않습니다. 화면에 보이는 이름은 앱의 센서 관리에서 언제든 수정할 수 있으므로, field_nm은 temp1, soil_a처럼 프로그램이 다루기 쉬운 값으로 두는 편이 좋습니다.

category 코드

코드 측정 항목 단위
01 온도 °C
02 습도 %
07 토양습도 %
09 광량(PPFD) μmol/m²/s
10 물온도 °C
12 이산화탄소 ppm
13 토양온도 °C
14 VPD kPa
15 EC dS/m

코드에 따라 아이콘과 단위, 소수점 자릿수가 정해집니다. 식물의 적정 범위와 비교해 알림을 보내는 기능도 이 코드를 기준으로 동작하므로 정확히 맞춰 주세요.


5. 요청 예제

Bash

#!/bin/bash
ACCESS_KEY="발급받은_Access_Key"
SECRET_KEY="발급받은_Secret_Key"
HOST="https://collector.seasonsingarden.life"
URI="/api/sensor/v1/data"

TIMESTAMP=$(($(date +%s) * 1000))
MESSAGE="POST ${URI}
${TIMESTAMP}
${ACCESS_KEY}"

SIGNATURE=$(printf '%s' "$MESSAGE" \
  | openssl dgst -sha256 -hmac "$SECRET_KEY" -binary \
  | base64)

curl -X POST "${HOST}${URI}" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ${ACCESS_KEY}" \
  -H "X-Timestamp: ${TIMESTAMP}" \
  -H "X-Signature: ${SIGNATURE}" \
  -d "{
    \"device_name\": \"베란다 파이\",
    \"date\": \"$(date -u '+%Y-%m-%d %H:%M:%S')\",
    \"sensors\": [
      {\"field_nm\": \"temp1\", \"category\": \"01\", \"unit\": \"°C\", \"data\": \"23.5\"}
    ]
  }"

Python

import base64
import hashlib
import hmac
import time

import requests

ACCESS_KEY = "발급받은_Access_Key"
SECRET_KEY = "발급받은_Secret_Key"
HOST = "https://collector.seasonsingarden.life"
URI = "/api/sensor/v1/data"

timestamp = str(int(time.time() * 1000))
message = f"POST {URI}\n{timestamp}\n{ACCESS_KEY}"
signature = base64.b64encode(
    hmac.new(SECRET_KEY.encode(), message.encode(), hashlib.sha256).digest()
).decode()

payload = {
    "device_name": "베란다 파이",
    "date": time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()),
    "sensors": [
        {"field_nm": "temp1", "field_kor_nm": "베란다 온도",
         "category": "01", "unit": "°C", "data": "23.5"},
        {"field_nm": "soil1", "field_kor_nm": "화분 토양습도",
         "category": "07", "unit": "%", "data": "42"},
    ],
}

response = requests.post(
    HOST + URI,
    json=payload,
    headers={
        "X-API-Key": ACCESS_KEY,
        "X-Timestamp": timestamp,
        "X-Signature": signature,
    },
)
print(response.status_code, response.text)

6. 응답 확인

정상적으로 처리되면 200 OK와 함께 데이터 수신 성공이 반환됩니다.

상태 의미 확인할 내용
200 수신 성공
401 Invalid Access Key 키를 확인할 수 없음 X-API-Key 헤더가 있는지, Access Key가 정확한지 확인합니다.
401 Invalid Signature 서명 불일치 서명 문자열 형식, timestamp 일치 여부, 기기 시계를 확인합니다.
301 http로 요청함 https로 다시 보냅니다.

401이 계속 나올 때

  • X-Timestamp와 서명 문자열 2번째 줄의 값이 완전히 같은지 확인합니다. 서명을 만든 뒤 timestamp를 다시 계산하면 값이 달라집니다.
  • 서명 문자열 마지막에 줄바꿈이 붙지 않았는지 확인합니다. echo 대신 printf '%s'를 사용해야 합니다.
  • 경로는 쿼리스트링 없이 /api/sensor/v1/data만 넣습니다.
  • 기기 시계가 실제 시각과 5분 이상 차이 나지 않는지 확인합니다.

7. 전송 주기

5분보다 짧은 주기로 보내면 서버에서 받지 않습니다. 5분 주기로 전송하세요. Ecowitt 게이트웨이도 같은 주기로 전송합니다.


8. 센서 등록 확인과 연결

첫 데이터가 전송되면 앱의 센서 관리 화면에 발급한 키 아래로 센서가 자동으로 나타납니다.

MY → 설정 → 센서 관리 → 발급한 Key 이름

센서가 보이면 센서를 열어 설치한 구역을 지정하고, 그 구역의 식물과 연결합니다. 연결을 마쳐야 식물 상세 화면과 내장소 화면에서 측정값을 볼 수 있습니다.

센서에 구역을 하나만 지정한 경우에만 식물을 선택할 수 있습니다. 구역과 식물의 관계는 장소와 구역 가이드를 참고해 주세요.

다음에 읽을 내용