บทที่ 9 การพัฒนา IoT ด้วยโปรโตคอล MQTT

9.1 แนวคิดพื้นฐานของ MQTT

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

MQTT ถูกนำมาใช้อย่างแพร่หลายในงาน Internet of Things (IoT) เนื่องจากอุปกรณ์ IoT เช่น ESP32, ESP8266 หรือไมโครคอนโทรลเลอร์ สามารถส่งข้อมูลจากเซนเซอร์ไปยังระบบส่วนกลางได้อย่างสะดวก

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

องค์ประกอบของ MQTT

การทำงานของ MQTT มีองค์ประกอบสำคัญ 3 ส่วน ได้แก่

1. Publisher

Publisher คืออุปกรณ์หรือโปรแกรมที่ทำหน้าที่ส่งข้อมูลเข้าสู่ระบบ ตัวอย่างเช่น

2. Subscriber

Subscriber คืออุปกรณ์หรือโปรแกรมที่ต้องการรับข้อมูล เช่น

Subscriber จะทำการ Subscribe Topic ที่สนใจ เช่น iot/sensor/ESP32-01 เมื่อมีข้อมูลใหม่ถูกส่งเข้ามา Subscriber จะได้รับข้อมูลนั้นโดยอัตโนมัติ

3. MQTT Broker

Broker เป็นตัวกลางในการรับและกระจายข้อความระหว่าง Publisher และ Subscriber ตัวอย่าง Broker ที่นิยมใช้ ได้แก่

โบรกเกอร์ MQTT มีหน้าที่หลัก คือ

  1. รับและกระจายข้อความ: ทำหน้าที่รับข้อมูลจาก Publisher และกระจายไปยัง Subscriber ที่สมัครรับข้อมูล
  2. กรองข้อความ: จัดการตรวจสอบว่าข้อมูลใดควรส่งไปให้ใคร
  3. ตรวจสอบสถานะการเชื่อมต่อของอุปกรณ์ (Client ID, Keep Alive)
  4. รักษาความปลอดภัย: ตรวจสอบสิทธิ์ (Authentication & Authorization) ของอุปกรณ์ที่เข้ามาเชื่อมต่อ

ประเภทของ MQTT Broker

  1. โบรกเกอร์แบบสาธารณะ/Cloud (Public/Managed MQTT Broker) เป็นโบรกเกอร์ที่ให้บริการอยู่บนอินเทอร์เน็ต สามารถใช้งานได้ทันที มักให้บริการโดยบริษัทต่างๆ ไม่ต้องดูแลเซิร์ฟเวอร์เอง ใช้งานง่าย (เช่น HiveMQ, EMQX Cloud, AWS IoT Core, Google Cloud IoT Core) อาจมีค่าใช้จ่ายเมื่อใช้งานปริมาณมาก หรือมีความเสี่ยงเรื่องความปลอดภัยหากตั้งค่าไม่ดี
  2. โบรกเกอร์แบบส่วนตัว/ติดตั้งเอง (Private/Self-hosted MQTT Broker) ติดตั้งและใช้งานภายในระบบเครือข่ายของตัวเอง (On-premise) เช่น บน Raspberry Pi, เซิร์ฟเวอร์บริษัท หรือ Docker ปลอดภัยสูง ข้อมูลไม่ถูกส่งออกภายนอก จัดการการเข้าถึงได้เองทั้งหมด

MQTT ใช้รูปแบบการสื่อสารที่เรียกว่า Publish/Subscribe หรือ Pub/Sub

Publisher ส่งข้อความด้วยคำสั่ง Publish

Subscriber ขอรับข้อความด้วยคำสั่ง Subscribe

Topic คืออะไร

Topic คือชื่อช่องทางที่ใช้จัดกลุ่มข้อมูลในระบบ MQTT ตัวอย่าง iot/sensor/ESP32-01 หมายถึงการตั้งหัวข้อเรื่องเกี่ยวกับ iot/sensor/ESP32-01 ดังนั้นอุปกรณ์ตัวไหนที่ต้องการรับข้อความในกลุ่มนี้ ก็จะต้องทำการ Subscribe ไว้ที่ห้วข้อเดียวกันนี้ และหากต้องการส่งข้อมูลให้กับอุปกรณ์ที่อยู่ในกลุ่มนี้ ก็ต้อง publish มาที่หัวข้อเดียวกันนี้ด้วยเช่นกัน

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

MQTT Message

ข้อมูลที่ Publisher ส่งผ่าน MQTT เรียกว่า Message ตัวอย่างแบบง่าย เช่น 28.52 หรือ 28.52,65.37 แต่ในการพัฒนาระบบ IoT มักนิยมใช้ JSON เพื่อให้ข้อมูลมีโครงสร้างชัดเจน เช่น

หากปรียบเทียบ TCP กับ MQTT สามารถเปรียบเทียบได้ดังนี้

ดังนั้น MQTT ไม่ได้หมายความว่าเป็นการ "แทนที่ TCP" ในทุกกรณี แต่เป็น โพรโทคอลระดับ Application Layer ที่ใช้การสื่อสารผ่านเครือข่าย TCP/IP และเพิ่มรูปแบบ Pub/Sub รวมถึงแนวคิด Topic และ Broker เข้ามาช่วยจัดการการสื่อสาร

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

การสื่อสารระหว่างอุปกรณ์ในเครือข่ายด้วยโปรโตคอล MQTT นั้น จะต้องสื่อสารผ่าน Broker ซึ่งทำหน้าที่เป็นตัวกลาง โดยผู้ส่ง Publisher จะทำหน้าที่ส่งไปยัง Broker ในหัวข้อ Topic ที่กำหนด และ Broker จะส่งต่อไปยังตัวลูกข่าย Subscriber ที่ลงทะเบียน Topic เดียวกันกับผู้ส่ง ก็จะได้รับข้อมูลได้พร้อม ๆ กัน

โดยในเบื้องต้น เราจะทดลองใช้โบรกเกอร์แบบสาธารณะ/Cloud (Public/Managed MQTT Broker) โดยใช้ โบรกเกอร์ hiev

ก่อนอื่นเราจะต้องหาเครื่องมือมาใช้ทดสอบระบบ โดยจะใช้โปรแกรม MQTT BOX ซึ่ง MQTT BOX คือเครื่องมือหรือซอฟต์แวร์ประเภท MQTT Client Tool ที่เอาไว้ใช้สำหรับทดสอบการทำงานของระบบ MQTT เปรียบเสมือน "รีโมทคอนโทรล" หรือ "หน้าต่าง" ที่ช่วยให้เราจำลองตัวเองเป็นอุปกรณ์ (Client) เพื่อไปเชื่อมต่อกับ Broker เพื่อดูว่าระบบรับ-ส่งข้อมูลได้ปกติไหม

MQTT Box เป็นได้ทั้งผู้ส่งและผู้รับ: สามารถทำหน้าที่เป็นทั้ง Publisher (ส่งข้อมูลเข้า Topic) และ Subscriber (รับข้อมูลจาก Topic) ในเวลาเดียวกัน

ใช้ดูว่าค่าที่เซนเซอร์ส่งออกมาจริงๆ คืออะไร (ดู Payload) ก่อนจะเอาไปเขียนโปรแกรมจริง โดยสามารถดาวน์โหลดได้จากลิ้ง Download MQTT BOX

ให้ดำเนินการติดตั้งและเปิดโปรแกรม จะมีหน้าต่างดังรูปแล้วให้กรอก ข้อมูล MQTT Client Name: MQTT Client ID: เลือกโปรโตคอล เป็น mqtt/tcp กำหนด Host เป็น broker.hivemq.com และกดปุ่ม Save ดังรูป

หากกำหนดค่าได้ถูก จะเห็นการเชื่อมต่อ connected เป็นสีเขียว ดังรูป

ให้เพิ่ม Add subscriber แล้วกำหนด Topic ให้ตรงกับ Publisher ดังรูป แล้วกดปุ่ม Subscribe

ทดลอง ส่งข้อความ Hello ใน Payload แล้วกดปุ่ม Publish จะเห็นข้อความ Hello ถูกส่งไปยังตัว subscriber ทุก ๆตัว ที่ subscribe หัวข้อเดียวกัน

ให้ทดลอง เป็น Subscriber ของหัวข้อเดียวกัน ดังรูป

การใช้ python รับส่งข้อมูลผ่าน MQTT

Python สามารถทำหน้าที่แทน MQTT Box ได้โดยตรง เพราะ MQTT Box เป็นเพียง MQTT Client ส่วน Python ก็สามารถเป็น MQTT Client ได้เช่นกัน Python package paho-mqtt เพราะจะเห็นโค้ดของ connect(), publish() และ subscribe() ชัดเจน

โดยต้องติดตั้ง ติดตั้ง Paho MQTT บนเครื่องคอมพิวเตอร์ โดยใช้คำสั่ง

     
      pip install paho-mqtt

     

จะเห็นกระบวนการติดตั้งดังรูป

แล้วตรวจสอบการติดตั้งด้วยคำสั่ง

     
     pip show paho-mqtt

     

จะเห็นผลการติดตั้ง ดังรูป

จากนั้น ให้เขียนโปรแกรมให้ Python ทำหน้าที่เป็นผู้ส่ง สามารถใช้ vs code สร้างโปรแกรม mqtt_publisher.py โดยใช้โค้ดตัวอย่างนี้

     
import paho.mqtt.client as mqtt

BROKER = "broker.hivemq.com"
PORT = 1883
TOPIC = "sunya/iot/test"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)

client.connect(BROKER, PORT)

message = "Hello MQTT from Python"

client.publish(TOPIC, message)

print("ส่งข้อมูล:", message)
print("Topic:", TOPIC)

client.disconnect()

จากนั้นให้รันโปรแกรม โดยใช้คำสั่ง python mqtt_publisher.py จะเห็นการทำงานของโปรแกรมส่งข้อความออกไปให้แก่ Broker โดยมีการแสดงผลบนหน้าจอผู้ส่งดังรูป

ให้ลองใช้ MQTT BOX ทำหน้าที่เป็นผู้รับ Subscriber ไว้ที่ Topic: sunya/iot/test เช่นเดียวกับตัวส่งจาก python แล้วให้ลอง รัน python เพื่อส่งอีกครั้ง จะเห็นข้อความจาก python ถูกส่งไปยัง subscriber โดยปรากฏข้อความที่ MQTT BOX ดังรูป

ให้สร้างผู้รับ Subscriber ด้วย python โดยใช้โค้ดด้านล่างเขียนลงใน vs code แล้วบันทึกเป็นไฟล์ชื่อ mqtt_subscriber.py

     
import paho.mqtt.client as mqtt

BROKER = "broker.hivemq.com"
PORT = 1883
TOPIC = "sunya/iot/test"


def on_connect(client, userdata, flags, reason_code, properties):
    print("เชื่อมต่อ MQTT Broker สำเร็จ")
    print("Subscribe:", TOPIC)

    client.subscribe(TOPIC)


def on_message(client, userdata, msg):
    message = msg.payload.decode()

    print("ได้รับข้อมูล")
    print("Topic  :", msg.topic)
    print("Message:", message)


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)

client.on_connect = on_connect
client.on_message = on_message

client.connect(BROKER, PORT)

print("กำลังรอข้อมูล...")

client.loop_forever()

ให้เปิด หน้าต่าง cmd อีกหน้า แล้วรัน ไฟล์ด้วยคำสั่ง python mqtt_subscriber.py เพื่อ subscribe รอข้อความจาก ผู้ส่ง โดยจะมีหน้าต่างดังรูป

จากนั้นให้รัน python ฝั่งตัวส่ง อีกครั้ง เพื่อทดสอบ การส่งจาก publisher ไปยัง subscriber ผ่านทาง broker ดังแสดงในรูป

การส่งข้อมูลผ่าน MQTT ด้วยข้อมูลรูปแบบ JSON

โดยข้อมูลรูปแบบ JSON จะมีลักษณะ อยู่ในเครื่องหมายปีกกา { } แต่ละข้อมูลจะประกอบด้วย Key (ชื่อฟิลด์ครอบด้วยเครื่องหมายคำพูด " ") ตามด้วยเครื่องหมายโคลอน : และตามด้วย Value (ค่าของข้อมูล) ตัวอย่างเช่น

โดยจะส่งผ่าน Topic: sunya/iot/ESP32-01 จากนั้นตัว Subscriber จะรับข้อมูล JSON แล้วแปลงกลับเป็นข้อมูล Python

ทดลองส่งข้อมูล Sensor ด้วย JSON โดยฝั่งตัว publisher ให้นำโค้ดด้านล่างไปเขียนด้วย vs code แล้วบันทึกเป็นไฟล์ชื่อ mqtt_publisher_json.py

     
import paho.mqtt.client as mqtt
import json
import random

BROKER = "broker.hivemq.com"
PORT = 1883
TOPIC = "sunya/iot/ESP32-01"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)

client.connect(BROKER, PORT)

# สร้างข้อมูลจำลองจาก Sensor
data = {
    "device_id": "ESP32-01",
    "temperature": round(random.uniform(25.0, 35.0), 2),
    "humidity": round(random.uniform(50.0, 80.0), 2)
}

# แปลง Python Dictionary เป็น JSON
message = json.dumps(data)

client.publish(TOPIC, message)

print("ส่งข้อมูลสำเร็จ")
print("Topic :", TOPIC)
print("Message:", message)

client.disconnect()   

 

จากนั้นรัน pyhton mqtt_publisher_json.py จะได้ผลลัพธ์ว่าตัว publisher ได้ส่งข้อมูล ไปยัง Broker แล้วดังรูป

สร้างโปรแกรมฝั่งตัวรับ Subscriber โดยใช้โค้ดด้านล่าง เขียนใน vs code แล้วบันทึกเป็นไฟล์ชื่อ mqtt_subscriber_json.py

     
import paho.mqtt.client as mqtt
import json

BROKER = "broker.hivemq.com"
PORT = 1883
TOPIC = "sunya/iot/ESP32-01"


def on_connect(client, userdata, flags, reason_code, properties):

    print("เชื่อมต่อ MQTT Broker สำเร็จ")
    print("Subscribe:", TOPIC)

    client.subscribe(TOPIC)


def on_message(client, userdata, msg):

    print("\nได้รับข้อมูล")
    print("Topic :", msg.topic)

    # แปลงข้อความ JSON เป็น Python Dictionary
    data = json.loads(msg.payload.decode())

    print("Device ID   :", data["device_id"])
    print("Temperature :", data["temperature"], "°C")
    print("Humidity    :", data["humidity"], "%")


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)

client.on_connect = on_connect
client.on_message = on_message

client.connect(BROKER, PORT)

print("กำลังรอข้อมูล...")

client.loop_forever()

 

จากนั้นรันไฟล์ subscriber ด้วยคำสั่ง python mqtt_subscriber_json.py จะเห็นตัว Subscriber รอรับข้อมูลดังรูป

จากนั้นทดลอง รันไฟล์ตัวส่งอีกครั้ง จะเห็นข้อมูลจากตัวส่งในรูปแบบ json มาแสดงผลบนตัวรับ ดังรูป

หัวข้อ