d
Dang Coffee Roaster
River Watch

อยากทำระบบแบบนี้กับกล้องของคุณเอง

คัดลอกข้อความด้านล่างไปวางใน LLM ที่เขียนโค้ดได้ (เช่น Claude Code, Codex, Cursor) แก้ส่วนที่อยู่ในวงเล็บมุมให้เป็นข้อมูลกล้องของคุณ แล้วส่งไปได้เลย

ก่อนเริ่ม

สิ่งที่ต้องมี: URL สตรีมกล้องที่เห็นไม้วัดระดับน้ำ และเครื่องที่รันได้ตลอด 24 ชั่วโมง (VPS เล็กๆ หรือคอมที่บ้านที่ไม่ปิด) ต้องมี ffmpeg กับ Python 3.10 ขึ้นไป
ถ้ากล้องของคุณไม่มีไม้วัดระดับน้ำอยู่ในภาพ วิธีนี้จะใช้ไม่ได้ เพราะระบบอ่านค่าจากขีดบนไม้วัด ไม่ได้เดาจากผิวน้ำเฉยๆ
ระบบนี้เผยแพร่ภายใต้สัญญาอนุญาต MIT นำวิธีการไปใช้ต่อได้โดยไม่ต้องขออนุญาต

Prompt

ผมต้องการสร้างเว็บแอปเฝ้าระวังระดับน้ำ โดยอ่านค่าจากกล้องวงจรปิดที่เห็นไม้วัดระดับน้ำ (staff gauge)

=== ข้อมูลที่ผมมี (แก้ตรงนี้ก่อนส่ง) ===
- URL สตรีมกล้อง: <ใส่ URL ของคุณ เช่น http://<ip-กล้องของคุณ>:8080/playlist.m3u8 หรือ rtsp://... หรือหน้าเว็บที่ฝังวิดีโอไว้>
- ชื่อจุดวัด: <เช่น สะพานบ้านxxx ตำบลxxx>
- ลักษณะไม้วัดในภาพ: <เช่น เสาเหลืองสลับดำ มีตัวเลขกำกับทุก 10 ซม. / หรือยังไม่ทราบ ให้ช่วยดูจากภาพ>
- ระดับที่ถือว่าเฝ้าระวัง / วิกฤต: <ถ้ายังไม่ทราบ บอกผมว่าต้องหาจากอะไร>

=== สิ่งที่ต้องการ ===
เว็บแอปที่เก็บระดับน้ำต่อเนื่องทุก 30 นาที และมีหน้าเว็บให้ประชาชนเปิดดูจากมือถือ
พร้อม API สาธารณะแบบ open data ไม่ต้องล็อกอิน

=== ขั้นตอนที่อยากให้ทำ ===
1. สำรวจแหล่งข้อมูลก่อนเขียนโค้ด
   ดึงหน้าเว็บ/สตรีมมาดูจริงว่าเป็นอะไร (HLS m3u8, RTSP, MJPEG, หรือภาพนิ่ง)
   ดึงภาพนิ่งออกมา 1 เฟรมด้วย ffmpeg แล้วเปิดดู อย่าเดาจากชื่อไฟล์

2. ดูภาพที่ได้ แล้วบอกผมว่าเห็นอะไร
   มีไม้วัดไหม สีอะไร ตัวเลขอ่านออกไหม มีป้ายหรือสิ่งกีดขวางบังหรือเปล่า
   มี timestamp ฝังในภาพไหม ถ้ามีให้เก็บไว้ด้วย

3. อ่านค่าด้วย computer vision ล้วน ห้ามใช้ LLM อ่านตัวเลขในขั้นตอนการวัดประจำ
   เหตุผล: LLM อ่านภาพเดียวกันห่างกันไม่กี่วินาทีให้ค่าต่างกันเป็นเมตรได้
   ทั้งยังช้าและแพง ให้ใช้ LLM แค่ช่วยตอนตั้ง calibration ครั้งแรกเท่านั้น
   วิธีที่ใช้ได้ผล: หาเสาไม้วัดจากคอลัมน์ที่มีสีเด่นหนาแน่นที่สุด (ใช้จุดกึ่งกลางของช่วง
   ไม่ใช่คอลัมน์เดียวที่ค่าสูงสุด เพราะมันสลับไปมาทุกเฟรมตามคลื่น)
   แล้วหาผิวน้ำจากขอบล่างของลายไม้วัด เพราะลายจะเห็นเฉพาะเหนือน้ำ

4. ทำ calibration แปลงแถวพิกเซลเป็นเมตร
   ซูมภาพให้ใหญ่จนอ่านตัวเลขบนไม้วัดออก แล้วให้ผมยืนยันว่าแต่ละป้ายคือกี่เมตร
   เก็บคู่ (แถวพิกเซล, เมตร) อย่างน้อย 10 จุดกระจายทั้งเสา แล้ว fit เป็นสมการ
   ใช้ quadratic ไม่ใช่ linear ถ้าเสาเอียงออกจากกล้อง (ระยะต่อ 1 ขีดจะไม่เท่ากันบนล่าง)
   รายงาน residual เป็นเซนติเมตรให้ผมดู ถ้าเกิน 3 ซม. แปลว่ายังไม่ดีพอ
   แล้ววาดเส้นสเกลทุกขีดทับภาพจริง ส่งให้ผมดูว่าเส้นตรงกับป้ายทุกเส้นหรือไม่
   ขั้นตอนนี้ห้ามข้าม ตัวเลขที่ไม่ได้ตรวจด้วยตาคือตัวเลขที่เชื่อไม่ได้

5. เก็บลง SQLite
   เก็บทั้งค่าระดับ เวลา ชื่อไฟล์ภาพ ความมั่นใจ และ error ถ้าอ่านไม่ได้
   เก็บภาพลงดิสก์แยกตามวัน และลบภาพที่เก่าเกินกำหนดอัตโนมัติ

6. หน้าเว็บ (สำคัญที่สุด เพราะประชาชนทั่วไปเป็นคนใช้)
   - หน้าหลัก: ระดับล่าสุดตัวใหญ่ สถานะ แนวโน้ม กราฟ 24 ชม. ภาพกล้องล่าสุด
   - หน้าประวัติ: เลือกช่วง 6 ชม. / 24 ชม. / 3 วัน / 7 วัน / 30 วัน
   - หน้าไทม์แลปส์: เล่นภาพย้อนหลังต่อเนื่อง มีปุ่มเล่น ปรับความเร็ว และแถบเลื่อน
     พร้อมกราฟที่มีเส้น playhead วิ่งตามภาพที่กำลังดู
   - ทุกหน้าใช้ภาษาไทย อ่านบนมือถือได้ ไม่ต้องใช้ CDN ภายนอกสำหรับกราฟ
     (ถ้าไลบรารีโหลดไม่ขึ้น หน้าเว็บจะพังตามไปด้วย ให้วาดด้วย canvas เอง)

7. API สาธารณะ
   เปิด CORS ให้ทุกโดเมน ไม่ต้องใช้ key มี endpoint บอกข้อมูลสถานี วิธีวัด
   และข้อจำกัดของค่า เพื่อให้คนที่เอาไปใช้ต่อตีความถูก มี CSV ให้ดาวน์โหลดด้วย

8. ตั้งเวลาเก็บข้อมูลทุก 30 นาทีด้วย cron และให้เว็บเซิร์ฟเวอร์ฟื้นเองถ้าล่ม

=== กฎการออกแบบที่อยากให้ทำตาม (เรียนรู้มาจากการทำจริง) ===
- วัด 3 เฟรมต่อรอบ กระจายห่างกันสัก 20 วินาที แล้วใช้ค่า median
  เก็บค่าความต่างระหว่างเฟรม (spread) ไว้ด้วย ถ้าเฟรมไม่ตรงกันมาก ให้ลดความมั่นใจลง
  อย่ารายงานความมั่นใจของเฟรมที่ชนะ ทั้งที่เฟรมอื่นอ่านได้ต่างกันมาก
- ถ้าอ่านไม่ได้ ให้บันทึกเป็น null พร้อมเหตุผล อย่าเดาค่า
- ตรวจว่ากล้องขยับหรือยัง โดยเก็บตำแหน่งเสาไว้ทุกครั้ง ถ้าเลื่อนเกินไม่กี่พิกเซล
  ให้ปฏิเสธการอ่าน ไม่ใช่รายงานว่าระดับน้ำเปลี่ยน
- กราฟสำหรับเฝ้าระวังน้ำท่วม ต้องไม่ใช่กราฟสวยอย่างเดียว
  * ใส่แถบสีพื้นหลัง เขียว/เหลือง/แดง ตามเกณฑ์ ตอบคำถาม "ต้องห่วงไหม" ก่อนอ่านตัวเลข
  * บังคับช่วงแกน Y ขั้นต่ำสัก 0.4 เมตร ไม่งั้น auto-scale จะขยายการกระเพื่อม
    ระดับเซนติเมตรจนดูเหมือนน้ำท่วม
  * ดึงเส้นเกณฑ์เฝ้าระวังเข้ามาในจอเมื่ออยู่ใกล้พอ เพื่อให้เห็นว่าเหลืออีกเท่าไร
  * ถ้าข้อมูลขาดช่วงเกิน 1-2 ชั่วโมง ให้ตัดเส้นกราฟ อย่าลากเส้นตรงข้ามช่วงที่ไม่มีข้อมูล
  * ป้ายแกนเวลาให้อิงช่วงเวลาที่มีข้อมูลจริง ไม่ใช่ช่วงที่ผู้ใช้เลือก
  * แสดงอัตราการเปลี่ยนแปลงเป็น ซม./ชม. โดย fit เส้นตรงจากข้อมูล 2 ชั่วโมงล่าสุด
    ไม่ใช่เอาค่าแรกลบค่าสุดท้าย และคำนวณต่อว่าอีกกี่ชั่วโมงจะถึงเกณฑ์เฝ้าระวัง
- ถ้าข้อมูลล่าสุดเก่าเกินรอบที่ควรจะเป็น ให้ขึ้นแถบเตือนบนหน้าเว็บว่าระบบอาจมีปัญหา
- มีหน้า/endpoint ที่วาดเส้นสเกลและเส้นผิวน้ำทับภาพจริง ให้ใครก็ตามตรวจค่าที่ระบบอ่านได้เอง
- ถ้าจะ render ภาพที่มีข้อความภาษาไทยด้วย Pillow ให้เลือกฟอนต์ที่มีทั้งอักษรไทย
  ตัวเลข และอักษรละตินในไฟล์เดียว (เช่น Garuda หรือ Waree)
  ฟอนต์อย่าง Noto Sans Thai ไม่มี glyph ตัวเลข ตัวเลขจะกลายเป็นกล่องเปล่าทั้งหมด
- อย่าเช็กว่าเซิร์ฟเวอร์ยังรันอยู่ด้วยการ match ชื่อโปรเซส เพราะ pattern จะไปตรงกับ
  shell ที่พิมพ์คำสั่งนั้นเอง ให้เช็กว่าพอร์ตเปิดฟังอยู่หรือไม่แทน
- เขียนข้อความกำกับให้ชัดว่าค่านี้เป็นข้อมูลประกอบ ไม่ใช่ประกาศเตือนภัยทางการ
  และแนะนำให้ผู้ใช้ยึดประกาศจากหน่วยงานราชการเป็นหลัก
  ค่าที่ได้คือระดับบนไม้วัดจุดนั้น ไม่ใช่ค่าอ้างอิงระดับทะเลปานกลาง

=== วิธีทำงานที่อยากให้ใช้ ===
ทำทีละขั้น และหยุดให้ผมยืนยันในขั้นที่ 2 (ดูภาพ) กับขั้นที่ 4 (calibration)
ก่อนไปต่อ เพราะสองขั้นนี้ผิดแล้วทุกอย่างหลังจากนั้นผิดตาม
เวลารายงานผล ให้แสดงตัวเลขจริงที่วัดได้ ไม่ต้องสรุปว่า "เสร็จแล้ว" เฉยๆ