HTTP API (Thiết bị)

Gửi telemetry, attributes và RPC qua HTTP từ thiết bị IoT đến VieLang IoT.

HTTP API (Thiết bị)

HTTP Transport cho phép thiết bị giao tiếp với VieLang IoT qua giao thức HTTP/HTTPS theo mô hình request-response. Phù hợp cho thiết bị không hỗ trợ MQTT hoặc cần request đơn giản.

Xác thực

Dùng Access Token trong URL path:

http://localhost:8080/api/v1/{ACCESS_TOKEN}/...

Error codes:

  • 400 — Payload không hợp lệ
  • 401 — Access Token sai
  • 404 — Thiết bị không tồn tại

Telemetry API

Gửi telemetry

POST http://localhost:8080/api/v1/{ACCESS_TOKEN}/telemetry Content-Type: application/json

Format 1 — Key-value:

curl -X POST http://localhost:8080/api/v1/ACCESS_TOKEN/telemetry \ -H "Content-Type: application/json" \ -d '{"temperature": 25.5, "humidity": 68}'

Format 2 — Có timestamp:

curl -X POST http://localhost:8080/api/v1/ACCESS_TOKEN/telemetry \ -H "Content-Type: application/json" \ -d '{"ts": 1735000000000, "values": {"temperature": 25.5, "humidity": 68}}'

Format 3 — Nhiều điểm:

curl -X POST http://localhost:8080/api/v1/ACCESS_TOKEN/telemetry \ -H "Content-Type: application/json" \ -d '[ {"ts": 1735000000000, "values": {"temperature": 25.5}}, {"ts": 1735000005000, "values": {"temperature": 25.8}} ]'

Upload từ file JSON:

curl -X POST http://localhost:8080/api/v1/ACCESS_TOKEN/telemetry \ -H "Content-Type: application/json" \ -d @sensor_data.json

Attributes API

Gửi client-side attributes

POST http://localhost:8080/api/v1/{ACCESS_TOKEN}/attributes curl -X POST http://localhost:8080/api/v1/ACCESS_TOKEN/attributes \ -H "Content-Type: application/json" \ -d '{"firmware": "v2.1.0", "battery": 87, "model": "ESP32-CAM"}'

Lấy shared attributes

GET http://localhost:8080/api/v1/{ACCESS_TOKEN}/attributes ?sharedKeys=targetFirmware,maxTemperature curl "http://localhost:8080/api/v1/ACCESS_TOKEN/attributes?sharedKeys=targetFirmware,maxTemperature" # Response: { "shared": { "targetFirmware": "v2.2.0", "maxTemperature": 35 } }

Lấy client-side attributes

GET http://localhost:8080/api/v1/{ACCESS_TOKEN}/attributes ?clientKeys=firmware,battery # Response: { "client": { "firmware": "v2.1.0", "battery": 87 } }

RPC API

Nhận lệnh từ server (long polling)

Thiết bị gửi GET và chờ đến khi có lệnh (timeout 30 giây):

GET http://localhost:8080/api/v1/{ACCESS_TOKEN}/rpc ?timeout=30000 curl "http://localhost:8080/api/v1/ACCESS_TOKEN/rpc?timeout=30000" # Response khi có lệnh: { "id": 1, "method": "setGpio", "params": { "pin": 4, "value": 1 } }

Phản hồi lệnh RPC

POST http://localhost:8080/api/v1/{ACCESS_TOKEN}/rpc/{requestId} Content-Type: application/json curl -X POST http://localhost:8080/api/v1/ACCESS_TOKEN/rpc/1 \ -H "Content-Type: application/json" \ -d '{"result": "ok", "pin": 4, "value": 1}'

Gửi Client-side RPC

POST http://localhost:8080/api/v1/{ACCESS_TOKEN}/rpc curl -X POST http://localhost:8080/api/v1/ACCESS_TOKEN/rpc \ -H "Content-Type: application/json" \ -d '{"method": "getCurrentTime", "params": {}}' # Response từ server: {"currentTime": 1735000000000}

Code mẫu

Python (requests)

import requests, json, time BASE_URL = "http://localhost:8080/api/v1" ACCESS_TOKEN = "YOUR_ACCESS_TOKEN" def send_telemetry(data: dict): r = requests.post( f"{BASE_URL}/{ACCESS_TOKEN}/telemetry", json=data, timeout=5 ) r.raise_for_status() def send_attributes(data: dict): r = requests.post( f"{BASE_URL}/{ACCESS_TOKEN}/attributes", json=data, timeout=5 ) r.raise_for_status() def poll_rpc(timeout_ms: int = 30000): r = requests.get( f"{BASE_URL}/{ACCESS_TOKEN}/rpc", params={"timeout": timeout_ms}, timeout=timeout_ms / 1000 + 5 ) if r.status_code == 200: return r.json() return None def respond_rpc(request_id: int, result: dict): requests.post( f"{BASE_URL}/{ACCESS_TOKEN}/rpc/{request_id}", json=result, timeout=5 ) # Main loop send_attributes({"firmware": "v2.1.0", "model": "ESP32"}) while True: # Gửi telemetry send_telemetry({"temperature": 25.5, "humidity": 68}) # Poll RPC (non-blocking) cmd = poll_rpc(timeout_ms=1000) if cmd: print(f"RPC: {cmd}") respond_rpc(cmd["id"], {"result": "ok"}) time.sleep(5)

Arduino / ESP32

#include <HTTPClient.h> #include <ArduinoJson.h> const char* ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"; const char* SERVER_URL = "http://192.168.1.100:8080"; void sendTelemetry(float temp, float hum) { HTTPClient http; String url = String(SERVER_URL) + "/api/v1/" + ACCESS_TOKEN + "/telemetry"; http.begin(url); http.addHeader("Content-Type", "application/json"); StaticJsonDocument<200> doc; doc["temperature"] = temp; doc["humidity"] = hum; String payload; serializeJson(doc, payload); int code = http.POST(payload); Serial.printf("Telemetry: HTTP %d\n", code); http.end(); }

So sánh HTTP vs MQTT

Tiêu chíHTTPMQTT
Giao thứcTCP request-responseTCP pub-sub
Kết nốiStatelessPersistent
OverheadCao hơnThấp hơn
Real-timeLong pollingNative push
Thích hợpThiết bị đơn giảnThiết bị nhiều dữ liệu
Tường lửaDễ vượt quaCần port 1883