โมดูล 4/5 · สัปดาห์ 10–12 · 27 ชม.

IoT และ WMS

UAT 363 เทคโนโลยีระบบอากาศยานไร้คนขับเพื่อการขนส่งและคลังสินค้าอัจฉริยะ

เวลาเรียนประมาณ 90 นาทีร่าง รอตรวจปรับปรุงล่าสุด 27 กันยายน 2569

บทเรียน

เมื่อเรียนจบโมดูลนี้ ผู้เรียนจะสามารถ

  1. ออกแบบการส่งข้อมูลจากโดรนผ่าน MQTT ด้วย topic และระดับ QoS ที่เหมาะสม
  2. ออกแบบข้อความผลสแกนในรูป JSON ที่ระบบบริหารคลังสินค้า (WMS) ใช้ได้
  3. กระทบยอดผลสแกนกับบันทึกใน WMS และคำนวณความถูกต้องของบันทึก
  4. ตรวจความถูกต้องของรหัสสินค้าด้วยเลขตรวจสอบตามมาตรฐาน GS1

ความรู้พื้นฐานที่ควรมี: UAT 363 โมดูล 3 · UAT 322 (IoT และ MQTT)

ทำไมต้องรู้

ผลสแกนที่อยู่แต่ในโดรนไม่มีประโยชน์ ข้อมูลต้องไหลเข้า ระบบบริหารคลังสินค้า (warehouse management system, WMS) เพื่อเทียบกับบันทึก แล้วแจ้งเจ้าหน้าที่เมื่อพบความคลาดเคลื่อน รายงาน ETH ระบุว่าการเชื่อมกับระบบเดิมเป็นข้อท้าทายหลักของโดรนในคลัง ถ้าข้อความหายระหว่างทาง ส่งซ้ำ หรือรหัสสินค้าอ่านผิด ระบบจะสรุปผิดว่าของหายหรือเกิน

MQTT ในคลังสินค้า

หน่วยความรู้เรื่อง MQTT และ Eclipse Mosquitto อธิบายสถาปัตยกรรม publish–subscribe ผู้ส่ง (โดรน) ส่งข้อความไปที่ topic บน broker และผู้รับ (WMS แดชบอร์ด) สมัครรับ topic นั้น ผู้ส่งกับผู้รับไม่ต้องรู้จักกันโดยตรง

โดรนสแกนส่งข้อความ publish ผ่าน topic warehouse/scan ไปที่ MQTT broker Mosquitto แล้ว broker ส่งต่อให้ WMS และแดชบอร์ดที่ subscribe
ภาพที่ 1 สถาปัตยกรรมโดรน MQTT และ WMS

มาตรฐาน MQTT 5.0 ของ OASIS กำหนด ระดับคุณภาพการส่ง (QoS) สามระดับ

QoSความหมายผลต่อผลสแกน
0ส่งอย่างมากหนึ่งครั้ง ข้อความอาจหายตำแหน่งตรงตามจริงอาจกลายเป็น “ไม่พบ”
1ส่งอย่างน้อยหนึ่งครั้ง อาจซ้ำผู้รับต้องจัดการข้อความซ้ำ เช่น ใช้รหัสข้อความ
2ส่งครั้งเดียวพอดีช้ากว่าเพราะต้องยืนยันหลายขั้น

ผลสแกนสินค้ามักใช้ QoS 1 ร่วมกับรหัสข้อความที่ไม่ซ้ำ ให้ผู้รับตัดข้อความซ้ำได้ ส่วนตำแหน่งโดรนที่ส่งถี่ ๆ อาจใช้ QoS 0 เพราะข้อความใหม่มาแทนเร็ว

ตัวอย่างที่ 1 ข้อความผลสแกนและการกระทบยอด

ข้อความ JSON หนึ่งข้อความต่อหนึ่งตำแหน่ง แล้วเทียบกับบันทึกใน WMS (ข้อมูลสมมติ 8 ตำแหน่ง)

import json

scan_msg = {"msg_id": "D1-20260927-0001", "location": "A1-03-2", "item": "4012345000016",
            "qty": 12, "ts": "2026-09-27T09:15:02+07:00", "drone": "D1"}
print("topic warehouse/scan/A1 payload", json.dumps(scan_msg))

wms = {"A1-01-1": ("4012345000016", 10), "A1-02-1": ("4012345000023", 5), "A1-03-2": ("4012345000016", 12),
       "A1-04-3": ("4012345000030", 8), "A1-05-1": ("4012345000047", 20), "A1-06-2": ("4012345000054", 6),
       "A1-07-4": ("4012345000061", 4), "A1-08-5": ("4012345000078", 9)}
scan = {"A1-01-1": ("4012345000016", 10), "A1-02-1": ("4012345000023", 3), "A1-03-2": ("4012345000016", 12),
        "A1-05-1": ("4012345000047", 20), "A1-06-2": ("4012345000054", 6), "A1-07-4": ("4012345000061", 4),
        "A1-08-5": ("4012345000078", 9), "A1-09-1": ("4012345000085", 2)}

result = {"match": [], "qty differs": [], "not found": [], "unexpected": []}
for loc, (item, qty) in wms.items():
    if loc not in scan:
        result["not found"].append(loc)
    elif scan[loc] == (item, qty):
        result["match"].append(loc)
    else:
        result["qty differs"].append(loc)
result["unexpected"] = [loc for loc in scan if loc not in wms]
for k, v in result.items():
    print(f"{k:<12} {len(v)} {v}")
print(f"record accuracy {len(result['match']) / len(wms):.1%} of {len(wms)} WMS locations")
topic warehouse/scan/A1 payload {"msg_id": "D1-20260927-0001", "location": "A1-03-2", "item": "4012345000016", "qty": 12, "ts": "2026-09-27T09:15:02+07:00", "drone": "D1"}
match        6 ['A1-01-1', 'A1-03-2', 'A1-05-1', 'A1-06-2', 'A1-07-4', 'A1-08-5']
qty differs  1 ['A1-02-1']
not found    1 ['A1-04-3']
unexpected   1 ['A1-09-1']
record accuracy 75.0% of 8 WMS locations

“ไม่พบ” อาจแปลว่าของหายจริง หรือโดรนอ่านป้ายไม่ได้ หรือข้อความ QoS 0 หาย ก่อนปรับบันทึกใน WMS ต้องให้เจ้าหน้าที่ตรวจยืนยัน และบันทึกสาเหตุ

ผลสแกนจากโดรนและบันทึกใน WMS เข้ากล่องเทียบรายตำแหน่ง ผลแยกเป็นสี่แบบ ตรงกัน จำนวนต่าง ไม่พบสินค้า และพบเกินจากบันทึก
ภาพที่ 2 กระทบยอดผลสแกนกับ WMS

รหัสสินค้าและเลขตรวจสอบ

รหัสสินค้าตามมาตรฐาน GS1 (GS1 General Specifications) มีหลักสุดท้ายเป็น เลขตรวจสอบ (check digit) คำนวณจากหลักอื่น ถ้ากล้องอ่านผิดหนึ่งหลัก เลขตรวจสอบมักไม่ตรง ระบบจึงปฏิเสธรหัสนั้นแทนการบันทึกสินค้าผิดรายการ

ตัวอย่างที่ 2 ตรวจเลขตรวจสอบของรหัส 13 หลัก

def gs1_check_digit(digits):                 # ไม่รวมหลักตรวจสอบ
    total = sum(int(d) * (3 if i % 2 == 0 else 1) for i, d in enumerate(reversed(digits)))
    return (10 - total % 10) % 10

def is_valid(code):
    return code.isdigit() and gs1_check_digit(code[:-1]) == int(code[-1])

for code in ("4012345000016", "4012348000016", "4012345000023"):
    print(f"{code}: check digit {gs1_check_digit(code[:-1])}, valid {is_valid(code)}")
4012345000016: check digit 6, valid True
4012348000016: check digit 3, valid False
4012345000023: check digit 3, valid True

รหัสที่สองอ่านผิดหนึ่งหลัก (5 เป็น 8) เลขตรวจสอบจึงไม่ตรง ระบบควรขอสแกนใหม่แทนการบันทึก

ปฏิบัติการประจำโมดูล

ปฏิบัติการ: ส่งผลสแกนเข้าระบบ

  1. ติดตั้ง Mosquitto ในแล็บ ใช้ paho-mqtt ส่งผลสแกนจากปฏิบัติการโมดูล 3 ตามรูปแบบข้อความในตัวอย่างที่ 1
  2. เขียนผู้รับที่บันทึกลงตาราง (แทน WMS) ตัดข้อความซ้ำด้วย msg_id แล้วทดลองส่งด้วย QoS 0 และ 1 ขณะตัดเครือข่ายชั่วคราว
  3. กระทบยอดผลสแกนกับบันทึก คำนวณความถูกต้องของบันทึก
  4. ตรวจเลขตรวจสอบของทุกรหัสที่อ่านได้ นับจำนวนที่ถูกปฏิเสธ
  5. เขียนขั้นตอนการยืนยันโดยเจ้าหน้าที่ก่อนปรับบันทึก

ข้อผิดพลาดที่พบบ่อย

ระวัง

  • ใช้ QoS 0 กับผลสแกน แล้วสรุปว่าของหาย
  • ไม่มีรหัสข้อความ ทำให้นับซ้ำเมื่อใช้ QoS 1
  • ปรับบันทึกใน WMS อัตโนมัติ โดยไม่ยืนยัน
  • ไม่ตรวจเลขตรวจสอบ จนบันทึกสินค้าผิดรายการ
  • ไม่ป้องกัน broker ด้วยการยืนยันตัวตนและการเข้ารหัส (ดูหน่วยความรู้ MQTT)

สรุป

  • MQTT แบบ publish–subscribe ส่งผลสแกนจากโดรนไปยัง WMS และแดชบอร์ด
  • QoS 0 อาจหาย QoS 1 อาจซ้ำ QoS 2 ครั้งเดียวพอดี เลือกตามผลต่อข้อมูล
  • กระทบยอดรายตำแหน่งเป็นสี่ผล และยืนยันก่อนปรับบันทึก
  • เลขตรวจสอบ GS1 จับการอ่านรหัสผิดได้

แบบฝึกตรวจความเข้าใจ

  1. QoS ใดที่ข้อความอาจซ้ำ
  2. ตรวจ 50 ตำแหน่ง ตรงกัน 46 ความถูกต้องของบันทึกเท่าใด
  3. ทำไมผลสแกนควรมีรหัสข้อความที่ไม่ซ้ำ
  4. เลข 12 หลักแรก 401234500001 เลขตรวจสอบคืออะไร
  5. ผล “ไม่พบสินค้า” มีสาเหตุที่เป็นไปได้อะไรบ้าง
เฉลย
  1. QoS 1
  2. ให้ผู้รับตัดข้อความซ้ำได้เมื่อใช้ QoS 1
  3. 6
  4. ของหายจริง อ่านป้ายไม่ได้ หรือข้อความหายระหว่างทาง

สรุปสูตรสำคัญ

ความถูกต้องของบันทึก
เลขตรวจสอบ GS1 (mod 10)

แหล่งอ้างอิงหลัก

  1. OASIS. (2019). MQTT version 5.0 (OASIS Standard, 7 March 2019). link
  2. Eclipse Foundation. Eclipse Mosquitto: An open source MQTT broker. link
  3. Eclipse Foundation. paho-mqtt: MQTT version 5.0/3.1.1 client class (Python package). link
  4. GS1. (2026). GS1 general specifications (Release 26.0). link
  5. Wawrla, L., Maghazei, O., & Netland, T. (2019). Applications of drones in warehouse operations (White paper). ETH Zurich, D-MTEC, Chair of Production and Operations Management. link
  6. Ma, Y., Selby, N., & Adib, F. (2017). Drone relays for battery-free networks. In Proceedings of ACM SIGCOMM 2017 (pp. 335–347). ACM. link
  7. Kurose, J. F., & Ross, K. W. (2025). Computer networking: A top-down approach (9th ed.). Pearson. link

อ่านเพิ่มเติม

ศึกษาหน่วยความรู้ที่กำหนดล่วงหน้า ดูสื่อประกอบ และทำ quiz ประจำโมดูล

ในชั้นเรียน / ภาคสนาม

ปฏิบัติการเข้มข้นในแล็บและภาคสนาม บันทึกผลลงสมุดปฏิบัติการ

หลักฐานการเรียนรู้: สมุดปฏิบัติการที่อาจารย์ลงนาม

แบบทดสอบประจำโมดูล

แบบทดสอบนี้ใช้ตรวจความเข้าใจ (formative) ไม่ใช่การสอบเก็บคะแนน

โดเมนความรู้: ขนส่ง ภายในอาคาร และคลังสินค้า · การสื่อสาร เครือข่าย และ IoT · การเขียนโปรแกรมและเทคโนโลยีดิจิทัล