API Documentation

v1 Stable

ยินดีต้อนรับเข้าสู่ระบบ API ของ PRO AI Vision แพลตฟอร์มที่ช่วยให้นักพัฒนาสามารถอ่านเลขมิเตอร์ไฟฟ้า เลขมิเตอร์น้ำ และเลขห้อง ได้อย่างแม่นยำด้วยเทคโนโลยี Vision AI ระบบของเราถูกออกแบบมาเพื่อความเสถียรและใช้งานง่ายสำหรับหอพักและบ้านเช่า

memory Vision AI Backend

https://core.vision.proiot.xyz/api/v1

Endpoint สำหรับการประมวลผลรูปภาพเพื่อดึงข้อมูลด้วย AI

rocket_launch เริ่มต้นใช้งาน

  1. สมัครและ Login ผ่าน Vision Web
  2. ไปที่ API Keys (/api-keys)
  3. กดสร้าง API Key ใหม่ และตั้งชื่อ (เช่น production)
  4. คัดลอกและเก็บ API Key ทันที — ระบบจะแสดงครั้งเดียวเท่านั้น
  5. ตรวจสอบว่ามี เครดิตคงเหลือ > 0 ก่อนเรียก API

รูปแบบ API Key:

sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

lock การยืนยันตัวตน (Authentication)

ทุก endpoint (ยกเว้น /health) ต้องส่ง header X-API-Key เพื่อยืนยันตัวตน

X-API-Key

HEADER: X-API-Key: {your_key}

เหมาะสำหรับการเรียกใช้แบบ Server-to-Server โดยคุณสามารถสร้าง Key ได้จาก Dashboard ของ Vision Web

curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/electric" \
  -H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "files=@meter_photo.jpg"
เงื่อนไข ผลลัพธ์
ไม่ส่ง X-API-Key HTTP 401
API Key ไม่ถูกต้องหรือถูกปิดใช้งาน HTTP 401 — Invalid or inactive API key
เครดิตไม่พอ (≤ 0) HTTP 403 — Insufficient credits
API Key ต้องอยู่ในสถานะ active เปิด/ปิดได้จากหน้า Dashboard → API Keys

data_object รูปแบบ Response

สำเร็จ (HTTP 200)

{
  "success": true,
  "data": { },
  "message": "ข้อความ"
}

ล้มเหลว

{
  "success": false,
  "message": "ข้อความ error",
  "errors": {
    "field": ["รายละเอียด"]
  }
}

ฟิลด์ errors จะมีเฉพาะกรณี validation error (HTTP 422)

API Endpoints

Method Path Auth คำอธิบาย
GET /health ไม่ต้อง ตรวจสอบสถานะบริการ
GET /api/v1/quota X-API-Key ตรวจเครดิตคงเหลือ
POST /api/v1/extract/electric X-API-Key อ่านมิเตอร์ไฟฟ้า
POST /api/v1/extract/water X-API-Key อ่านมิเตอร์น้ำ

health_and_safety GET /health — Health Check

GET

รายละเอียด

ตรวจสอบว่าบริการทำงานอยู่

ไม่ต้องส่ง API Key

curl https://core.vision.proiot.xyz/health

Response 200

{
  "success": true,
  "data": null,
  "message": "Service is running"
}

account_balance_wallet GET /api/v1/quota — เครดิตคงเหลือ

GET

รายละเอียด

Auth

X-API-Key

คืนค่า

เครดิตคงเหลือ (credits_remaining)

curl https://core.vision.proiot.xyz/api/v1/quota \
  -H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Response 200

{
  "success": true,
  "data": {
    "credits_remaining": 18
  },
  "message": "Quota retrieved successfully"
}

photo_camera เคล็ดลับการถ่ายรูป

ถ่าย 1 รูป หลายมิเตอร์ — ระบบตรวจจับมิเตอร์ทุกตัวในรูปเดียวและคืนผลเป็น array ใน data ใช้วิธีนี้เพื่อลดจำนวนไฟล์และประหยัดเครดิต (หักตามจำนวนไฟล์ ไม่ใช่จำนวนมิเตอร์)

แนวทาง รายละเอียด
แนะนำ จัดให้มิเตอร์อยู่ในเฟรมเดียวกัน ชัดเจน อ่านเลขได้
จำนวนต่อรูป ไม่เกิน 5–8 ตัวต่อรูป เพื่อความแม่นยำ
หลีกเลี่ยง รูปมืด เบลอ มิเตอร์ซ้อนทับกันจนอ่านไม่ได้

ตัวอย่าง: อาคาร 20 ห้อง — ถ่าย 4 รูป (มิเตอร์ 5 ตัว/รูป) แทน 20 รูป → ใช้เครดิต 4 แทน 20

electric_bolt POST /api/v1/extract/electric

POST

อ่านมิเตอร์ไฟฟ้า — Content-Type: multipart/form-data

หลายมิเตอร์ต่อรูปได้ — แนะนำไม่เกิน 4–6 ตัวต่อรูป

Parameters

files Required

file[] — รูปมิเตอร์ไฟ (1–20 ไฟล์)

curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/electric" \
  -H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "files=@electric.jpg"

Example Response

{
  "success": true,
  "data": {
    "total": 1,
    "success_count": 1,
    "failed_count": 0,
    "results": [{
      "rid": 1,
      "filename": "electric.jpg",
      "success": true,
      "data": [{
        "id": 1,
        "room_no": "660",
        "label": "MEA No. 920",
        "value": 4035.7,
        "box": [50, 100, 200, 300]
      }],
      "error": null
    }],
    "credits_remaining": 14
  },
  "message": "Meter extraction completed"
}

water_drop POST /api/v1/extract/water

POST

อ่านเลขหลักดำ (ลบ.ม.) จากมิเตอร์น้ำ — ไม่รวมเลขแดง/หน่วยย่อย

Parameters

files Required

file[] — รูปมิเตอร์น้ำ (1–20 ไฟล์)

curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/water" \
  -H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "files=@water1.jpg" \
  -F "files=@water2.jpg"

Example Response

{
  "success": true,
  "data": {
    "total": 2,
    "success_count": 2,
    "failed_count": 0,
    "results": [{
      "rid": 1,
      "filename": "water1.jpg",
      "success": true,
      "data": [{
        "id": 1,
        "room_no": "660",
        "label": null,
        "value": 12345,
        "box": [120, 80, 350, 280]
      }]
    }],
    "credits_remaining": 15
  },
  "message": "Meter extraction completed"
}

crop_free วาดกรอบ Bounding Box ฝั่ง Client

API คืนพิกัด box เป็น [ymin, xmin, ymax, xmax] แบบ normalized 0–1000 — แนะนำให้วาดกรอบบนรูปต้นฉบับฝั่ง client เพื่อไม่ใช้พื้นที่จัดเก็บบนเซิร์ฟเวอร์

พิกัด สูตรแปลง (ใช้ขนาดรูปต้นฉบับ)
real_ymin (ymin / 1000) × height
real_xmin (xmin / 1000) × width
real_ymax (ymax / 1000) × height
real_xmax (xmax / 1000) × width

นำ results[].data[] จาก response มาวาดกรอบสีแดงพร้อม label room_no / value แล้วเซฟหรือแสดงรูปฝั่งคุณเอง

# pip install pillow
from PIL import Image, ImageDraw, ImageFont

def draw_boxes(image_path: str, meters: list, output_path: str = "boxed.jpg") -> str:
    """box = [ymin, xmin, ymax, xmax] normalized 0–1000"""
    img = Image.open(image_path).convert("RGB")
    draw = ImageDraw.Draw(img)
    w, h = img.size
    line_width = max(3, int(w * 0.003))

    try:
        font = ImageFont.load_default(size=int(h * 0.02))
    except TypeError:
        font = ImageFont.load_default()

    for item in meters:
        box = item.get("box")
        if not box or len(box) != 4:
            continue

        ymin, xmin, ymax, xmax = box
        x1 = int((xmin / 1000) * w)
        y1 = int((ymin / 1000) * h)
        x2 = int((xmax / 1000) * w)
        y2 = int((ymax / 1000) * h)

        draw.rectangle([x1, y1, x2, y2], outline="red", width=line_width)

        room = item.get("room_no") or "N/A"
        value = item.get("value")
        label = f"Room: {room} | Val: {value}"
        label_h = max(14, int(h * 0.03))
        draw.rectangle([x1, y1 - label_h, x1 + int(w * 0.25), y1], fill="red")
        draw.text((x1 + 5, y1 - label_h + 2), label, fill="white", font=font)

    img.save(output_path, format="JPEG", quality=90)
    return output_path

# ใช้กับผลลัพธ์จาก API
# meters = response["data"]["results"][0]["data"]
# draw_boxes("electric.jpg", meters, "electric_boxed.jpg")

05 ระบบเครดิต

รายการ รายละเอียด
อัตราหัก จำนวนไฟล์ × อัตราต่อบริการ (default 1 เครดิต/ไฟล์)
ช่วงหัก หักล่วงหน้าก่อนประมวลผล
คืนเครดิต ไฟล์ที่ประมวลผลล้มเหลวจะคืนเครดิตอัตโนมัติ
ตรวจสอบยอด GET /api/v1/quota

ข้อจำกัด

รายการ ค่า
ขนาดไฟล์สูงสุด10 MB/ไฟล์
จำนวนไฟล์ต่อ requestสูงสุด 20 ไฟล์
มิเตอร์ต่อรูป (แนะนำ)5–8 ตัว/รูป
ขนาดรูปresize อัตโนมัติถ้าด้านยาวเกิน 1536 px
Timeout ต่อไฟล์60 วินาที (อาจได้ HTTP 504)
รูปแบบไฟล์JPEG, PNG ฯลฯ

06 รหัส HTTP ที่พบบ่อย

error

401 Unauthorized

ไม่ส่ง API Key หรือ Key ไม่ถูกต้อง/ถูกปิด

payments

403 Forbidden

เครดิตไม่พอ (Insufficient credits)

warning

400 Bad Request

ไฟล์ใหญ่เกิน / batch เกิน 20 / รูปอ่านไม่ได้

rule

422 Unprocessable Entity

Validation error (เช่น ไม่ส่ง files)

schedule

504 Gateway Timeout

AI timeout — หากทุกไฟล์ใน request timeout จะได้ error ทั้ง request

ตัวอย่าง error response

{
  "success": false,
  "message": "Insufficient credits: 2 available, 5 required (5 files x 1 credit/file)"
}

code ตัวอย่างโค้ด (รวม)

# Health check
curl https://core.vision.proiot.xyz/health

# เครดิตคงเหลือ
curl https://core.vision.proiot.xyz/api/v1/quota \
  -H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# มิเตอร์ไฟ
curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/electric" \
  -H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "files=@meter.jpg"

# มิเตอร์น้ำ
curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/water" \
  -H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "files=@meter.jpg"

คำถามที่พบบ่อย

Q: สร้าง API Key ได้ที่ไหน?

A: Login เข้า Vision Web → Dashboard → API Keys → สร้าง key ใหม่ หรือ คลิกที่นี่

Q: ลืมเก็บ API Key ทำอย่างไร?

A: ลบ key เดิมและสร้างใหม่ — ระบบไม่แสดง key เต็มซ้ำ

Q: ทำไมได้ 403?

A: เครดิตไม่พอ — ตรวจด้วย GET /api/v1/quota

Q: อัปโหลดหลายรูปใน request เดียวได้ไหม?

A: ได้ สูงสุด 20 ไฟล์ — ส่ง field files ซ้ำหลายครั้ง

Q: ถ่ายรูปเดียวที่มีหลายมิเตอร์ได้ไหม?

A: ได้ — ระบบตรวจจับทุกมิเตอร์ในรูป แนะนำไม่เกิน 5–8 ตัวต่อรูป