ตั้งชื่อ MQTT topic เผื่อวันที่มีหลายอุปกรณ์

ตั้งชื่อ MQTT topic เผื่อวันที่มีหลายอุปกรณ์ - Image 1
09/07/2025•Admin Team•
IoTMQTTTutorial

ตอนมีบอร์ดเซนเซอร์เพียงตัวเดียว การตั้งชื่อ topic ว่า temperature ก็ยังพอเดาได้ว่ามันส่งค่าจากไหน เพราะทั้งคนเขียนและคนเปิด Dashboard รู้จักอุปกรณ์ตัวนั้นอยู่แล้ว แต่พอเพิ่มบอร์ดอีกห้องเข้ามา เราก็เริ่มต้องแยกว่าอุณหภูมิที่เห็นเป็นของห้องไหน และถ้ามีคนเอาข้อมูลไปใช้อีกระบบ เขาจะรู้จักชื่อนี้เหมือนเราหรือเปล่า

ปัญหาจึงค่อยๆ เปลี่ยนจากการทำให้บอร์ดส่งข้อมูลได้ ไปเป็นการทำให้คนกับระบบหลายฝั่งเข้าใจข้อมูลชุดเดียวกันได้ด้วย ซึ่งชื่อ topic เป็นส่วนหนึ่งที่ต้องตกลงกันก่อน เพราะมันถูกใช้ทั้งตอนส่ง ตอนเลือกรับ และตอนกำหนดสิทธิ์ให้อุปกรณ์เข้าถึงข้อมูล

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

ตั้งชื่อให้รู้จักอุปกรณ์ แต่ไม่ต้องเล่าทุกอย่างในชื่อ

ลองใช้ตัวอย่างสมมติเป็นอาคารที่มีเซนเซอร์อยู่หลายห้อง แต่ละตัวส่งอุณหภูมิกับความชื้น ถ้าเราเริ่มจากสถานที่ ตามด้วยห้อง อุปกรณ์ และชนิดข้อมูล ชื่อที่ได้ก็อาจเป็นแบบนี้

site-a/room-01/sensor-01/state/temperature
site-a/room-01/sensor-01/state/humidity
site-a/room-02/sensor-02/state/temperature

จุดที่อยากให้สังเกตคือทุกชื่อใช้ลำดับเดียวกัน คนที่ไม่เคยเห็นโค้ดก็ยังพอไล่ได้ว่าข้อมูลอยู่ในกลุ่มไหน ส่วนคำว่า sensor-01 ควรเป็นรหัสที่ตั้งใจใช้ต่อ ไม่เปลี่ยนตามชื่อเล่นที่คนเรียกในแต่ละวัน เพราะระบบที่รับข้อมูลอาจจำรหัสนี้ไว้แล้ว

แต่ถ้ามีทั้งหมายเลขชิป รุ่นบอร์ด ชื่อคนติดตั้ง และวันที่เปลี่ยนแบต ก็ไม่จำเป็นต้องใส่ทุกอย่างต่อเข้าไปใน topic ข้อมูลที่ใช้อธิบายรายละเอียดอุปกรณ์สามารถเก็บเป็น metadata แยกไว้ได้ ชื่อควรมีสิ่งที่ช่วยเลือกเส้นทางข้อมูลจริงๆ เพื่อไม่ให้ทุกครั้งที่แก้รายละเอียดเล็กน้อยกลายเป็นการเปลี่ยนชื่อที่หลายระบบใช้อยู่

ตัวอย่างโครงสร้าง MQTT topic แยกสถานที่ ห้อง อุปกรณ์ และชนิดข้อมูล

คนรับจะเลือกข้อมูลเป็นกลุ่มอย่างไร

พอมีโครงชื่อแล้ว ลองมองจากฝั่งคนรับบ้าง ถ้า Dashboard ต้องดูอุณหภูมิทุกห้อง มันควรต้องระบุเซนเซอร์ทีละตัว หรือสามารถเลือกรับจากกลุ่มชื่อที่จัดไว้ได้ การลองเขียนรูปแบบที่ต้อง subscribe ตั้งแต่ตอนนี้จะช่วยบอกว่าโครงที่เลือกสะดวกกับงานจริงหรือไม่

MQTT ใช้ + สำหรับหนึ่งระดับของชื่อ และใช้ # สำหรับหลายระดับ โดย wildcard ใช้ในตัวกรองตอน subscribe ไม่ใช่ชื่อที่อุปกรณ์ใช้ publish ข้อมูล ตัวอย่างที่เลือกรับอุณหภูมิของทุกห้องและทุกเซนเซอร์ในอาคารเดียวกันอาจเขียนเป็น site-a/+/+/state/temperature ส่วนการรับทุกอย่างใต้ site-a ก็ใช้ site-a/#

อย่างไรก็ตาม การรับทุกอย่างสะดวกตอนตรวจระบบ แต่ไม่ควรกลายเป็นคำตอบเริ่มต้นของทุกบริการ ถ้าหน้าจอหนึ่งใช้เฉพาะสถานะอุณหภูมิ ก็เลือกขอบเขตเท่าที่ต้องใช้ จะได้ไม่ต้องนำคำสั่งหรือข้อมูลอุปกรณ์ชนิดอื่นมาคัดทิ้งในแอปอีกที

รายละเอียดเล็กๆ อย่างตัวพิมพ์ใหญ่เล็กและระดับชื่อที่เกิดจากเครื่องหมาย / ก็ต้องใช้ให้ตรงกันด้วย ถ้าฝั่งหนึ่งส่ง Temperature แต่อีกฝั่งรอ temperature ก็อาจดูเหมือนอุปกรณ์ไม่ส่งข้อมูล ทั้งที่ข้อความกำลังวิ่งไปอยู่อีกชื่อหนึ่งแล้ว

คำสั่งกับสถานะควรแยกให้อ่านออก

เมื่อระบบเริ่มควบคุมอุปกรณ์ได้ จะมีข้อมูลสองทิศทางที่หน้าตาคล้ายกัน คือสิ่งที่อยากให้อุปกรณ์ทำกับสิ่งที่อุปกรณ์บอกว่าทำอยู่ ถ้าใช้ชื่อเดียวกันโดยไม่ตกลงความหมาย อาจตามไม่ออกว่าข้อความล่าสุดเป็นคำขอหรือเป็นผลที่เกิดขึ้นจริง

ตัวอย่างการแยกชื่ออาจเป็น site-a/room-01/fan-01/command สำหรับคำสั่ง และ site-a/room-01/fan-01/state สำหรับสถานะ อุปกรณ์ที่รับคำสั่งเปิดพัดลมจึงควรตรวจและรายงานสถานะกลับมา ไม่ใช่ให้หน้าจอถือว่าการ publish สำเร็จเท่ากับพัดลมทำงานแล้ว

ตัวอย่างเส้นทางคำสั่งและสถานะของอุปกรณ์บน MQTT topic คนละชื่อ

ถ้าอยากตามคำสั่งแต่ละรอบได้ ก็ใส่รหัสคำสั่งไว้ใน payload แล้วให้สถานะตอบกลับอ้างถึงรหัสนั้นได้ด้วย เรื่องนี้เป็นข้อตกลงของแอปที่เราต้องออกแบบเพิ่ม ไม่ใช่สิ่งที่เกิดขึ้นเองเพียงเพราะตั้งชื่อ topic แยกกันแล้ว

ส่วนค่าที่ใช้บอกสถานะล่าสุดกับคำสั่งที่เป็นเหตุการณ์ครั้งเดียวก็ควรพิจารณาคนละแบบ โดยเฉพาะเมื่อต้องใช้ retained message เพราะคำสั่งเก่าที่ถูกส่งให้คนรับใหม่อาจมีผลต่างจากการส่งสถานะเก่าให้หน้าจอดูมากทีเดียว

ชื่อกับ payload ต้องเปลี่ยนรุ่นไปด้วยกันได้

ถึงชื่อ topic จะเหมือนเดิม รูปแบบข้อมูลข้างในก็อาจเปลี่ยนได้ เช่น จากเดิมส่งเพียงตัวเลข กลายเป็น JSON ที่มีทั้งค่า หน่วย และเวลาวัด ถ้าเปลี่ยนทันทีโดยไม่ดูผู้รับเก่า หน้าจอที่เคยอ่านได้ก็อาจพัง ทั้งที่ตรวจชื่อแล้วทุกอย่างยังตรงกัน

จึงควรจดรูปแบบ payload ไว้คู่กับโครงชื่อด้วย ว่าฟิลด์ไหนจำเป็น ใช้หน่วยอะไร และเวลาที่ส่งหมายถึงเวลาวัดหรือเวลาส่ง ถ้าต้องเปลี่ยนแบบที่ผู้รับเดิมอ่านต่อไม่ได้ อาจแยกเส้นทางรุ่นใหม่หรือวางช่วงเปลี่ยนผ่านให้ผู้รับย้ายตามได้ก่อน

การใส่เลขรุ่นใน topic เป็นเพียงทางเลือกหนึ่ง ไม่จำเป็นต้องเพิ่มทุกครั้งที่แก้ firmware หากความหมายของข้อมูลยังเหมือนเดิม สิ่งที่ต้องดูจริงๆ คือผู้รับยังทำงานกับข้อมูลชุดใหม่ได้หรือไม่ และมีใครใช้ชื่อเดิมอยู่บ้าง

ก่อนใช้กับหลายอุปกรณ์ ลองตรวจให้ครบหนึ่งเส้นทาง

เริ่มจากอุปกรณ์ตัวเดียว ส่งค่าหนึ่งชนิด แล้วตรวจว่าผู้รับที่เลือกชื่อแบบตรงตัวและแบบเป็นกลุ่มเห็นข้อมูลตามที่ตั้งใจหรือไม่ จากนั้นลองเพิ่มอุปกรณ์อีกตัวโดยไม่เปลี่ยนโค้ดของตัวแรก เพื่อดูว่าการแบ่งกลุ่มยังใช้ได้ตามโครงเดิมหรือเปล่า

เมื่อมีการกำหนดสิทธิ์ใน broker ก็ควรตรวจตามโครงนี้ด้วย อุปกรณ์หนึ่งตัวอาจต้องเขียนได้เฉพาะสถานะของตัวเอง และอ่านเฉพาะคำสั่งที่ส่งถึงมัน ชื่อที่จัดเป็นลำดับชัดจะช่วยให้เขียนขอบเขตเหล่านี้ได้ตรงขึ้น แต่ยังต้องตั้งสิทธิ์จริงใน broker เพราะชื่อที่ดูเป็นส่วนตัวไม่ได้ป้องกันการเข้าถึงด้วยตัวมันเอง

สรุป

การตั้งชื่อ MQTT topic เผื่อหลายอุปกรณ์ควรเริ่มจากสิ่งที่คนส่งกับคนรับต้องเข้าใจร่วมกัน แล้วใช้ลำดับชื่อที่สม่ำเสมอ แยกคำสั่งออกจากสถานะ และเก็บข้อตกลงของ payload ไว้ด้วย เมื่อเพิ่มอุปกรณ์หรือเปลี่ยนรุ่นข้อมูล ก็จะตามได้ว่ากระทบผู้รับกับสิทธิ์ส่วนไหนบ้าง โดยไม่ต้องเริ่มจัดทางเดินข้อมูลใหม่ทั้งระบบครับ

Command Eng Logo
CMD yourNgineers
เลขประจำตัวผู้เสียภาษี0805564000814
บทความ
ติดต่อบริษัท คอมมานด์ เอ็นจ์ จำกัด
81/36 เพอร์เฟค พาร์คบางนาตำบลบางเสาธง อำเภอบางเสาธงจังหวัดสมุทรปราการ 10570
team@commandeng.in.th+66 89 393 5191
Facebook Page | Command EngLine | Command Eng Official
© Copyright 2022-2026 Command Eng Co., Ltd.v1.0.4 · 0d556ab · 2026-11-03 15:23