EP09: Flask และ JSON

ส่วนที่ 1:

API คืออะไร? รู้จักกับ Flask และ JSON

ตัวกลางเรียกว่า API (Application Programming Interface)

  • เปรียบเทียบ API กับ “พนักงานรับออเดอร์”:
    • ลูกค้า (ESP32): มีข้อมูลที่อยากจะส่ง (เช่น อุณหภูมิ 45.5 C)
    • พนักงานรับออเดอร์ (API): คอยรับ “ออเดอร์” จากลูกค้าผ่านช่องทางที่กำหนด (เรียกว่า Endpoint)
    • ห้องครัว (ฐานข้อมูล): จัดเก็บข้อมูลตามที่พนักงานนำมาส่ง

หลักการทำงานเบื้องหลัง API

  • Client-Server Model:
    • Client (ผู้ร้องขอ): อุปกรณ์ที่ต้องการส่งหรือขอข้อมูล (เช่น ESP32, เว็บเบราว์เซอร์)
    • Server (ผู้ให้บริการ): โปรแกรมที่เรารันไว้ (สคริปต์ Python ของเรา) คอยรอรับคำขอตลอดเวลา
  • HTTP (Hypertext Transfer Protocol): “ภาษา” ที่ Client กับ Server ใช้คุยกัน
  • HTTP Methods (คำกริยาที่ใช้สั่งงาน):
    • GET: ขอข้อมูลไปดู (เหมือน SELECT)
    • POST: ส่งข้อมูลใหม่ไปให้บันทึก (เหมือน INSERT) -> คือหัวใจของวันนี้
  • JSON (JavaScript Object Notation):
    • “รูปแบบใบออเดอร์” ที่เป็นมาตรฐานสากล อ่านง่ายทั้งสำหรับคนและคอมพิวเตอร์
    • ตัวอย่าง: ข้อมูลจาก ESP32 จะถูกจัดรูปแบบเป็น JSON แบบนี้ก่อนส่ง:
JSON
{
  "machine_id": 1,
  "type": "temperature",
  "value": 45.5
}

แนะนำ Flask: เฟรมเวิร์คจิ๋วแต่แจ๋วสำหรับสร้าง API

  • Flask คืออะไร?: เป็น “ชุดเครื่องมือสำเร็จรูป” ใน Python ที่ช่วยให้เราสร้าง Web Server และ API ได้อย่างรวดเร็วและง่ายดาย โดยไม่ต้องเขียนโค้ดที่ซับซ้อนเองทั้งหมด
  • แนวคิดหลักของ Flask:
    • Route (เส้นทาง/Endpoint): การกำหนด URL ที่ Client จะต้องส่งข้อมูลเข้ามา เช่น http://your-server-ip/api/log
    • View Function: ฟังก์ชัน Python ที่จะทำงานเมื่อมี Request วิ่งเข้ามาที่ Route นั้นๆ

ส่วนที่ 2: การฝึกปฏิบัติ

หัวข้อ: Workshop: พัฒนา API Server สำหรับบันทึกข้อมูลเซ็นเซอร์

เครื่องมือ: คอมพิวเตอร์ที่มี Python, VS Code, และ Database Connector ที่ติดตั้งไว้แล้ว

ขั้นตอนที่ 1: ติดตั้ง Flask และเตรียมโปรเจกต์

  1. เปิด Command Prompt หรือ Terminal
  2. ติดตั้ง Flask: pip install Flask
  3. ใน VS Code, สร้างไฟล์ใหม่ชื่อ api_server.py
  4. นำโค้ดเชื่อมต่อฐานข้อมูลจากสัปดาห์ที่ 8 มาเตรียมไว้ในไฟล์เดียวกัน (เราจะเอามันมาใส่ในฟังก์ชันทีหลัง)

ขั้นตอนที่ 2: เขียน API Server ด้วย Flask

  • ภารกิจ: สร้าง API ที่มี 1 Endpoint (/api/log) ที่สามารถรับ POST request ที่มีข้อมูล JSON และบันทึกลงฐานข้อมูลได้
  • อธิบายโค้ดทีละส่วน
Python
from flask import Flask, request, jsonify
import psycopg2 # หรือ import mysql.connector

# --- ส่วนที่ 1: สร้างแอปพลิเคชัน Flask ---
app = Flask(__name__)

# --- ส่วนที่ 2: ข้อมูลสำหรับเชื่อมต่อฐานข้อมูล ---
conn_params = {
    "host": "127.0.0.1",
    "database": "smart_factory_week4",
    "user": "your_username",
    "password": "your_password"
}

# --- ส่วนที่ 3: สร้าง Endpoint (ประตูรับข้อมูล) ---
@app.route('/api/log', methods=['POST'])
def log_sensor_data():
    # 1. รับข้อมูล JSON จาก request
    data = request.get_json()
    print(f"ได้รับข้อมูล: {data}")

    # 2. ตรวจสอบข้อมูลเบื้องต้น
    if not data or 'machine_id' not in data or 'type' not in data or 'value' not in data:
        return jsonify({"status": "error", "message": "ข้อมูลไม่ครบถ้วน"}), 400

    # 3. ดึงค่าจาก JSON มาใส่ในตัวแปร
    machine_id = data['machine_id']
    metric_type = data['type']
    metric_value = data['value']

    conn = None
    try:
        # 4. เชื่อมต่อฐานข้อมูล
        conn = psycopg2.connect(**conn_params)
        cur = conn.cursor()

        # 5. สร้างคำสั่ง SQL และ Execute
        sql = "INSERT INTO sensor_logs (machine_id_fk, metric_type, metric_value) VALUES (%s, %s, %s);"
        cur.execute(sql, (machine_id, metric_type, metric_value))

        # 6. Commit การเปลี่ยนแปลง
        conn.commit()
        cur.close()

        # 7. ส่งคำตอบกลับไปหา Client ว่าสำเร็จ
        print("บันทึกข้อมูลสำเร็จ!")
        return jsonify({"status": "success", "message": "บันทึกข้อมูลเรียบร้อย"}), 201

    except Exception as error:
        print(f"เกิดข้อผิดพลาด: {error}")
        return jsonify({"status": "error", "message": str(error)}), 500

    finally:
        if conn is not None:
            conn.close()

# --- ส่วนที่ 4: สั่งให้แอปพลิเคชันทำงาน ---
if __name__ == '__main__':
    # host='0.0.0.0' เพื่อให้เครื่องอื่นในวง LAN เดียวกันมองเห็นได้
    app.run(host='0.0.0.0', port=5000, debug=True)

ขั้นตอนที่ 3: รันและทดสอบ API Server

  1. ใน Terminal ของ VS Code, สั่งรัน server: python api_server.py
  2. สังเกตผลลัพธ์: จะเห็นข้อความว่า Server กำลังทำงานที่ http://0.0.0.0:5000/

ขั้นตอนที่ 4: จำลองเป็น Client เพื่อส่งข้อมูล (Simulate ESP32)

  • วิธีที่ 1 (ใช้ curl ใน Terminal):
    • เปิด Terminal ใหม่ (อย่าปิดอันที่รัน server)
    • พิมพ์คำสั่ง curl เพื่อส่ง POST request
Bash
curl -X POST -H "Content-Type: application/json" -d '{"machine_id": 1, "type": "temperature", "value": 45.8}' http://127.0.0.1:5000/api/log
  • วิธีที่ 2 (สร้างไฟล์ Python อีกไฟล์ client_test.py):
    • ติดตั้งไลบรารี requests: pip install requests
    • เขียนโค้ดเพื่อส่งข้อมูล:
Python
import requests import json api_url = "http://127.0.0.1:5000/api/log" sensor_data = { "machine_id": 2, "type": "pressure", "value": 150.25 } response = requests.post(api_url, json=sensor_data) print(f"Status Code: {response.status_code}") print(f"Response: {response.json()}")

รันไฟล์ client_test.py แล้วสังเกตผลลัพธ์ทั้งฝั่ง client และ server

ตรวจสอบผลลัพธ์: ให้นักศึกษาใช้ DBeaver หรือโปรแกรม Database Client เปิดดูตาราง sensor_logs จะต้องเห็นข้อมูลใหม่ที่เพิ่งส่งเข้าไป