API 使用指南

RIVO 平台對所有已驗證的 API 端點採用端對端 AES-GCM 加密。所有受保護的請求必須在 HTTP 標頭中攜帶 Authorization Bearer Token,並傳送加密後的 JSON 請求體。

6.1 身份驗證

取得伺服器公鑰

登入前,先取得伺服器的 RSA 公鑰:

GET /api/v1/auth/key

回應:
{
  "success": true,
  "data": { "public_key": "-----BEGIN PUBLIC KEY-----\n..." }
}

登入(E2E 加密)

RIVO 採用混合式 RSA-OAEP + AES-GCM 登入流程:

  1. 生成 32 位元組的隨機 AES Session Key。
  2. 以 RSA-OAEP-SHA256 加密 {"username","password","session_key"}
  3. POST 加密後的 Base64 密文。
  4. 以 AES Session Key 解密伺服器回應,取得 Token。
POST /api/v1/auth/login
Content-Type: application/json

{
  "encrypted_data": "<base64(RSA-OAEP(payload))>"
}

解密後的回應 Payload:
{
  "access_token":     "eyJ...",
  "refresh_token":    "eyJ...",
  "certification_key": "ck_...",
  "account_id":       "acc_...",
  "expires_at":       "2026-01-01T00:00:00Z"
}

更新 Token(Refresh)

使用純 JSON(不加密)請求更新 Token:

POST /api/v1/auth/refresh
Content-Type: application/json

{ "refresh_token": "eyJ..." }

回應:
{
  "success": true,
  "data": {
    "access_token":  "eyJ...",
    "refresh_token": "eyJ..."
  }
}
注意:後續所有請求以 SHA-256(access_token) 衍生 32 位元組 AES 金鑰, 並將請求體封裝為 {"encrypted_data":"<base64(nonce || ciphertext+tag)>"}。 RIVO Node SDK 會自動處理此加解密流程。

6.2 機器人管理

註冊機器人

將 Node 節點註冊到機器人車隊。每次啟動均可安全呼叫——若已存在則回傳 409(可忽略)。

POST /api/v1/robots
Authorization: Bearer <access_token>

{
  "robot_id":   "turtlebot-001",
  "robot_type": "turtlebot3",
  "robot_name": "倉庫機器人 #1",
  "group_id":   "warehouse-a"    // 選填
}

回應 200: { "success": true }
回應 409: 機器人已存在(啟動時可忽略)

6.3 狀態與遙測

更新機器人狀態

心跳與狀態上報(RIVO Node 預設間隔:2 秒)。

POST /api/v1/robots/{robotId}/status
Authorization: Bearer <access_token>

// 加密請求體(AES-GCM),明文 Payload 範例:
{
  "status": {
    "battery_level": 85,
    "cpu_usage":     12.4,
    "state":         "active"
  }
}

上報感測器遙測

推送感測器主題資料(RIVO Node 預設間隔:500 毫秒)。

POST /api/v1/robots/{robotId}/telemetry
Authorization: Bearer <access_token>

// 明文 Payload 範例:
{
  "timestamp": "2026-01-01T00:00:00Z",
  "topics": {
    "temperature": { "value": 36.5, "unit": "°C" },
    "humidity":    { "value": 62.1, "unit": "%" }
  }
}

6.4 警報(Alert)

從機器人 Node 立即送出警報(不做批次彙整)。

POST /api/v1/robots/{robotId}/alert
Authorization: Bearer <access_token>

{
  "alert_type": "battery_low",
  "severity":   "warning",       // info | warning | error
  "message":    "電池僅剩 10%",
  "action":     "return_to_base",
  "timestamp":  "2026-01-01T00:00:00Z"
}

6.5 相機串流

RIVO Node 透過 LiveKit WebRTC 發布 VP8 相機影像串流。Node 啟動後會自動取得 Room Token 並開始串流。

取得串流 Token

GET /api/v1/robots/{robotId}/token?identity=camera
Authorization: Bearer <access_token>

// 解密後的回應 Payload:
{
  "token": "<LiveKit JWT>",
  "host":  "wss://livekit.example.com",
  "room":  "turtlebot-001"
}

RIVO Node 接著自動連線到 LiveKit,並以下列 GStreamer Pipeline 發布 TrackLocalStaticRTP VP8 影像軌:

gst-launch-1.0 v4l2src device=/dev/video0 \
  ! image/jpeg,width=1280,height=720,framerate=30/1 \
  ! jpegdec \
  ! vp8enc error-resilient=partitions keyframe-max-dist=10 \
            auto-alt-ref=true cpu-used=5 deadline=1 \
  ! rtpvp8pay mtu=1100 \
  ! udpsink host=127.0.0.1 port=<自動分配>

可透過 config.yamlcameras[*].gst_pipeline 欄位,指定自訂 GStreamer Pipeline。

6.6 指令與控制

透過加密 WebSocket 頻道向機器人發送指令。Node 啟動後即自動訂閱指令頻道,並對每條指令回傳確認。

WebSocket 指令頻道

WS /api/v1/robots/{robotId}/commands?token=<access_token>

// 伺服器 → Node(AES-GCM 加密 JSON):
{
  "id":         "cmd-uuid",
  "type":       "gripper_open",
  "parameters": { "force": 10 },
  "timestamp":  "2026-01-01T00:00:00Z"
}

// Node → 伺服器 ACK(AES-GCM 加密 JSON):
{
  "command_id": "cmd-uuid",
  "status":     "completed",   // received | in_progress | completed | failed
  "message":    "夾爪已開啟"
}

6.7 Node 設定檔參考(config.yaml

node:
  robot_id:   "my-robot-001"   # 未設定時自動由 machine-id 衍生
  robot_type: "custom"
  robot_name: "我的 RIVO Node"
  group_id:   ""

server:
  url:             "http://server:8080"
  timeout_seconds: 10

auth:
  mode:     "access_token"   # 或 "cert_key"
  username: "admin@rivo.io"  # 設定即觸發自動登入
  password: "password"
  # 或直接填入預先核發的 Token:
  # access_token:  "eyJ..."
  # refresh_token: "eyJ..."

cameras:
  - name:      "main"
    enabled:   true
    device:    "/dev/video0"
    width:     1280
    height:    720
    framerate: 30
    # gst_pipeline: "" # 選填,完整自訂 Pipeline

telemetry:
  status_interval:    "2s"
  telemetry_interval: "500ms"

uarts:
  mcu:
    enabled:  true
    port:     "/dev/ttyUSB0"
    baud:     115200
    framing:  "cobs"   # 或 slip
    encoding: "json"   # 或 cbor
    protocol: "bme280"

i2c:
  enabled: false
  bus:     1

spool:
  enabled: false

protocols:
  dir: "protocols"

logging:
  level: "info"

6.8 端對端加密(E2E)細節

所有已驗證的 API Payload 均採用 AES-256-GCM 加密。金鑰衍生方式如下:

aes_key = SHA-256(raw_access_token_string)   // 32 位元組

Wire Format:
  encrypted_data = base64( nonce[12 bytes] || ciphertext || GCM-tag[16 bytes] )

JSON 封裝:
  { "encrypted_data": "<base64>" }

RIVO Node SDK(internal/server/crypto.go)透過 EncryptPayload / DecryptPayload 自動處理金鑰衍生、加密與解密,開發者無需手動操作。