กำลังโหลด...

📡 SmartFarm API

API สำหรับอุปกรณ์เซนเซอร์ส่งข้อมูลเข้าระบบ (ESP8266, ESP32, Raspberry Pi ฯลฯ)
ยืนยันตัวตนด้วย signature (MD5) ทุกครั้ง

v1.0
Base URL https://<region>-<project-id>.cloudfunctions.net
POST /sensorData ส่งข้อมูลเซนเซอร์เข้าระบบ
คำอธิบาย

รับข้อมูลจากอุปกรณ์เซนเซอร์และบันทึกลงฐานข้อมูล ระบบใช้ HMAC signature (MD5) เพื่อยืนยันตัวตน โดย signature = md5(apiKey + timestamp + uid)

Request Body (Content-Type: application/json)
Field Type Required คำอธิบาย
uid string required UID ของเซนเซอร์ที่ลงทะเบียนในระบบ
timestamp number required Unix milliseconds (Date.now()) หรือ seconds (แปลงอัตโนมัติ) ต้องไม่เกิน 5 นาทีจากเวลาปัจจุบัน
signature string required MD5 hash ของ apiKey + timestamp + uid เพื่อยืนยันตัวตน
temperature number optional อุณหภูมิ (°C)
humidity number optional ความชื้นสัมพัทธ์ (%)
light number optional ความเข้มแสง (lux)
battery number optional แบตเตอรี่ (%) เช่น 87.5
Signature Formula: signature = md5(apiKey + timestamp + uid)
เช่น md5("sk_abc" + "1700000000000" + "S_xyz") = "d41d..."
ตัวอย่าง Request Body
{ "uid": "S_xxxxxxxxxxxxxxxx", "timestamp": 1700000000000, "signature": "d41d8cd98f00b204e9800998ecf8427e", "temperature": 28.5, "humidity": 65.2 }
Response Codes
200
OK — บันทึกข้อมูลสำเร็จ
{ "success": true, "uid": "ABC123xyz", "greenhouse": "gh-id-xxx", "data": { "uid": "ABC123xyz", "sensorName": "เซนเซอร์ A", "sensorType": "temperature", "temperature": 28.5, "humidity": 65.2, "timestamp": 1700000000000 } }
400
Bad Request — ไม่มี uid หรือเซนเซอร์ไม่ได้ผูกโรงเรือน
{"error": "Missing required field: uid"}
{"error": "Sensor is not linked to any greenhouse."}
401
Unauthorized — Signature ไม่ถูกต้อง
{"error": "Invalid signature."}
404
Not Found — ไม่พบ UID ในระบบ
{"error": "Sensor UID not found: ABC123xyz"}
405
Method Not Allowed — ใช้ได้เฉพาะ POST
{"error": "Method not allowed. Use POST."}
ตัวอย่างโค้ด
ESP8266 / Arduino
ESP32 (WiFiClient)
cURL
Python
// ต้องติดตั้ง library: ESP8266WiFi, ESP8266HTTPClient, ArduinoJson, MD5Builder #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <ArduinoJson.h> #include <MD5Builder.h> const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD"; const char* apiUrl = "https://<region>-<project>.cloudfunctions.net/sensorData"; const char* apiKey = "YOUR_FARM_API_KEY"; const char* sensorUid = "YOUR_SENSOR_UID"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } } String md5Sign(String key, String ts, String uid) { MD5Builder md5; md5.begin(); md5.add(key + ts + uid); md5.calculate(); return md5.toString(); } void sendSensorData(float temp, float humid) { if (WiFi.status() != WL_CONNECTED) return; WiFiClientSecure client; client.setInsecure(); HTTPClient http; http.begin(client, apiUrl); http.addHeader("Content-Type", "application/json"); String ts = String(millis()); // ใช้ NTP time จริงในโปรดักชัน String sig = md5Sign(apiKey, ts, sensorUid); StaticJsonDocument<256> doc; doc["uid"] = sensorUid; doc["timestamp"] = ts; doc["signature"] = sig; doc["temperature"] = temp; doc["humidity"] = humid; String body; serializeJson(doc, body); int code = http.POST(body); Serial.println(String("HTTP: ") + code); http.end(); } void loop() { sendSensorData(28.5, 65.0); delay(30000); }
// ESP32 — ใช้ mbedtls สำหรับ MD5 #include <WiFi.h> #include <HTTPClient.h> #include <WiFiClientSecure.h> #include <ArduinoJson.h> #include "mbedtls/md5.h" const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD"; const char* apiUrl = "https://<region>-<project>.cloudfunctions.net/sensorData"; const char* apiKey = "YOUR_FARM_API_KEY"; const char* sensorUid = "YOUR_SENSOR_UID"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } } String computeMD5(String input) { unsigned char digest[16]; mbedtls_md5((const unsigned char*)input.c_str(), input.length(), digest); String result = ""; for (int i = 0; i < 16; i++) { char buf[3]; sprintf(buf, "%02x", digest[i]); result += buf; } return result; } void sendData(float temp, float humid, float light) { WiFiClientSecure client; client.setInsecure(); HTTPClient http; http.begin(client, apiUrl); http.addHeader("Content-Type", "application/json"); String ts = String((long long)millis()); // ใช้ NTP time จริงในโปรดักชัน String sig = computeMD5(String(apiKey) + ts + String(sensorUid)); StaticJsonDocument<300> doc; doc["uid"] = sensorUid; doc["timestamp"] = ts; doc["signature"] = sig; doc["temperature"] = temp; doc["humidity"] = humid; doc["light"] = light; String body; serializeJson(doc, body); int code = http.POST(body); Serial.printf("HTTP %d\n", code); http.end(); } void loop() { sendData(28.5, 65.0, 1200); delay(30000); }
# 1. สร้าง signature ก่อน (Linux/Mac) TS=$(date +%s000) SIG=$(echo -n "YOUR_FARM_API_KEY${TS}YOUR_SENSOR_UID" | md5sum | cut -d' ' -f1) # 2. ส่ง request curl -X POST \ "https://<region>-<project>.cloudfunctions.net/sensorData" \ -H "Content-Type: application/json" \ -d "{ \"uid\": \"YOUR_SENSOR_UID\", \"timestamp\": $TS, \"signature\": \"$SIG\", \"temperature\": 28.5, \"humidity\": 65.0, \"light\": 1200 }"
import hashlib, time, requests url = "https://<region>-<project>.cloudfunctions.net/sensorData" API_KEY = "YOUR_FARM_API_KEY" SENSOR_UID = "YOUR_SENSOR_UID" ts = str(int(time.time() * 1000)) sig = hashlib.md5((API_KEY + ts + SENSOR_UID).encode()).hexdigest() payload = { "uid": SENSOR_UID, "timestamp": ts, "signature": sig, "temperature": 28.5, "humidity": 65.0, "light": 1200, } resp = requests.post(url, json=payload) print(resp.status_code, resp.json())
การบันทึกข้อมูล

เมื่อส่งข้อมูลสำเร็จ ระบบจะบันทึกลง Firebase Realtime Database 2 ตำแหน่ง:

// ค่าล่าสุด รวมทุก sensor (overwrite) sensors/{greenhouseId}/current → { temperature, humidity, light, updatedAt } // ค่าล่าสุด แยกตาม sensor UID (overwrite) sensors/{greenhouseId}/bySensor/{sensorUid} → { sensorName, sensorType, temperature, ... } // ประวัติ (push ทุกครั้ง) sensors/{greenhouseId}/history/{pushKey} → { uid, sensorName, temperature, ..., updatedAt }
POST /reportIp รายงาน IP address ของ Raspberry Pi
คำอธิบาย

Pi รายงาน local IP address ปัจจุบันเข้าระบบ เพื่อให้แสดงในหน้าฟาร์ม
ยืนยันตัวตนด้วย farmId และ apiKey ของฟาร์ม

Request Body
FieldTypeRequiredคำอธิบาย
farmId string required ID ของฟาร์ม (ดูได้จากหน้าฟาร์ม)
apiKey string required API Key ของฟาร์ม
ip string required IP address ของ Pi เช่น "192.168.1.100"
ตัวอย่าง Python (bridge.py)
import socket, time, requests FARM_ID = "your-farm-id" API_KEY = "YOUR_FARM_API_KEY" URL = "https://<region>-<project>.cloudfunctions.net/reportIp" def get_local_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.connect(("8.8.8.8", 80)) return s.getsockname()[0] finally: s.close() def report_ip(): ip = get_local_ip() resp = requests.post(URL, json={"farmId": FARM_ID, "apiKey": API_KEY, "ip": ip}) print(f"[IP] {ip} → {resp.status_code}")
Response Codes
200
OK — อัปเดต IP สำเร็จ
400
Bad Request — ขาด field ที่จำเป็น
403
Forbidden — apiKey ไม่ถูกต้อง
404
Not Found — ไม่พบ farmId