หลักการประมวลผลกราฟน้ำมัน

สรุปอัลกอริทึมแปลงค่าเซนเซอร์แรงดัน → เส้น "ปริมาณน้ำมัน" ที่การเติมเป็นขั้นตั้งฉาก และการใช้เป็นเส้นลาดเรียบ · สำหรับทีม dev นำไป implement ในแพลตฟอร์มใดก็ได้

Dev Handoff · platform-agnostic · log server VID 109338

ไฟล์สำหรับ dev

📊

กราฟ Interactive

กราฟจริง ปรับ invert / ความสมูท / เกณฑ์ต่างๆ ได้สด

📖

อธิบายโค้ด (ละเอียด)

ไล่ทีละขั้นตอน พร้อมโค้ดจริงและตัวอย่าง

📋

ดูข้อมูล (ตาราง)

615 records ในเบราว์เซอร์ · ค้นหา/กรอง/เรียงได้ ไม่ต้องโหลด

📥

ข้อมูลดิบ (Excel)

log server VID 109338 · 615 records · ต้นทางทั้งหมด

เวอร์ชัน Google Sheets

สรุป Code.gs (Apps Script) วิธีติดตั้ง + ใช้งาน

🗄️

เวอร์ชัน T-SQL (SQL Server)

สรุปทีละฟังก์ชัน + ดาวน์โหลด fuel_graph.sql

โจทย์: เซนเซอร์ BD ให้ค่า แรงดันไฟ (voltage) ไม่ใช่ลิตร และมี 2 ปัญหาที่ต้องแก้

1. กลับหัว

แรงดันต่ำ = น้ำมันเยอะ (ผกผันกับปริมาณจริง)

2. noise เยอะ

มี spike กระตุก + ช่วงเซนเซอร์หลุดปนมา

เป้าหมาย: เส้นน้ำมันที่อ่านง่าย — การเติม = ขั้นตั้งฉาก · การใช้ = เส้นลาดเรียบ

Pipeline 7 ขั้น — ทำอะไร + ทำไม

#หลักการทำไมต้องทำ
1กรองเฉพาะติดเครื่อง
เอาเฉพาะ record ที่ ignition bit = 1 (IO_STATUS เลขฐานสอง 16 หลัก หลักแรก = 1)
ตอนดับเครื่องเซนเซอร์ค่าเพี้ยน อย่าเอามาคิด
2กลับหัว (invert)
fuel = PIVOT − voltage โดย PIVOT = min + max ของค่าที่ใช้งานได้
ให้ "เส้นสูง = น้ำมันเยอะ" · PIVOT คิดจากข้อมูลเอง → ปรับตามทุกสเกล
3ตัดค่าอุปกรณ์ปิด
ตัดค่าที่ต่ำกว่า LOW (แรงดันตกวูบใกล้ 0 ทั้งที่น้ำมันยังอยู่)
ค่าพวกนี้คือเซนเซอร์หลุด ไม่ใช่น้ำมันจริง
4ตัด spike (Hampel filter)
จุดไหนห่างจาก median ของเพื่อนบ้าน 7 จุด เกิน N × MAD → ทิ้ง
ใช้ median/MAD (robust) ไม่ใช่ mean/std เพราะ spike จะไม่ลากเกณฑ์เพี้ยน
5สมูทแบบแบ่งช่วง
เฉลี่ยเคลื่อนที่ 15 จุด แต่ไม่ข้ามขอบจุดเติม (แบ่ง segment ที่จุดเติมก่อน)
ถ้าเฉลี่ยข้ามจุดเติม ขอบจะถูกลบให้มน กลายเป็นเนินลาด
6จับจุดเปลี่ยน
= ขนาดการเปลี่ยนน้ำมัน > EDGE (ไม่สนติด/ดับเครื่อง)
จับได้ทั้งเติมตอนจอด idle และตอนดับเครื่อง
7วาดขั้นตั้งฉาก
ที่จุดเปลี่ยน แทรก 2 จุดที่ เวลาเดียวกัน (ค่าเก่า → ค่าใหม่)
ต้องใช้แกนเวลาแบบตัวเลข ไม่ใช่ category ไม่งั้นเส้นจะเฉียง
8แยกประเภทเหตุการณ์ตามทิศทาง
Δ > +EDGE = เติมน้ำมัน · Δ < −EDGE = น้ำมันหายผิดปกติ
เติม/หาย สวนทางกัน · การใช้ปกติค่อยๆ ลด (< EDGE) ไม่ถูกนับ

สูตรจับเหตุการณ์: เติม ↔ น้ำมันหายผิดปกติ

🔄 สองเหตุการณ์นี้เป็น "กระจกเงา" กัน — เกณฑ์เดียวกัน ต่างแค่ทิศทาง

// คิดเป็นปริมาณน้ำมัน (กลับหัวแล้ว) · Δ = ค่าใหม่ − ค่าเก่า ที่จุดเปลี่ยน
Δ > +EDGE   →  ⛽ เติมน้ำมัน (refuel)        ขึ้นฮวบ
Δ < −EDGE   →  ⚠️ น้ำมันหายผิดปกติ (loss)  ลงฮวบ · รั่ว/ถูกดูด

คั่นจากการใช้ปกติอย่างไร: การใช้น้ำมันปกติลดช้าๆ (~14% ของช่วงต่อจุด, ต่ำกว่า EDGE) จึงไม่ถูกนับ · เฉพาะ ลงเร็วผิดธรรมชาติ เท่านั้นที่ถือเป็น "น้ำมันหาย" — dev ปรับความไวได้ด้วยการเพิ่ม/ลด EDGE หรือเทียบกับอัตราการใช้ปกติ (median slope)

หัวใจที่ทำให้ robust: เกณฑ์ "คิดจากข้อมูลเอง"

🎯 ไม่ฝังตัวเลขตายตัว → รองรับเซนเซอร์ทุกสเกล (0–2V, 0–10V, …) โดยไม่แก้โค้ด

LOW          = 0.4  × median(ค่า BD ตอนติดเครื่อง)     // เกณฑ์ตัดอุปกรณ์ปิด
EDGE         = 0.2  × (max − min ของช่วงใช้งานจริง)    // เกณฑ์จับจุดเติม
Hampel floor = 0.02 × ช่วงกว้าง                          // กันตัดมั่วตอนข้อมูลนิ่ง

ตรรกะของ EDGE: ใช้น้ำมันปกติ จุดต่อจุดขยับ ~14% ของช่วง · การเติมขยับ 28–86% · ตั้งไว้ 20% จึงคั่นกลางได้พอดี ทุกสเกล

ทดสอบ: ได้ผลเหมือนกันทุกสเกล

สเกลช่วงค่า BDLOW (auto)EDGE (auto)ตัดปิดตัด spikeจับจุดเติม
×1 (เดิม)0.83–1.690.600.1769342 ✓
×6 (0–10)4.98–10.143.581.0369342 ✓
×0.5 (เล็ก)0.41–0.840.300.0969342 ✓

3 กับดักที่ dev ต้องรู้

พารามิเตอร์ (ปรับได้)

พารามิเตอร์ค่า defaultหน้าที่
Hampel window7ขนาดหน้าต่างหา median เพื่อนบ้าน
Hampel sigma (N)3ความเข้มตัด spike (น้อย = ตัดเยอะ)
Smooth window15จำนวนจุดในหน้าต่างเฉลี่ยเคลื่อนที่
LOW / EDGE / floorautoคิดเป็นสัดส่วนของข้อมูล (ตารางด้านบน)

เอกสารประกอบ (โค้ดจริง): fuel_graph.html · fuel_graph_อธิบายโค้ด.html · Code.gs (Google Sheets)
log server VID 109338 · ประมวลผล 615 records