MQTT ====== | การเชื่อมต่อ Platform ผ่าน MQTT (Message Queuing Telemetry Transport) ซึ่งเป็น Protocol ที่มีขนาดเล็กและได้รับความนิยมสำหรับการสื่อสารแบบ M2M ( Machine to Machine ) โดยสามารถใช้ MQTT Library ตัวใดก็ได้ที่รองรับกับ Device ที่ใช้งานอยู่ การเชื่อมต่อของ MQTT จะต้องใช้ 4 Parameters คือ Host, Client ID, Username และ Password โดยให้ระบุแต่ละค่าดังนี้ | :Host: |broker_url| :Port: 1883 (mqtt), 1884 (mqtts) :Client ID: Client ID ของ Device ที่สร้างขึ้นใน |platform_name| :Username: Token ของ Device ที่สร้างขึ้นใน |platform_name| :Password: ยังไม่ต้องระบุ (ใช้สำหรับกรณีที่ต้องการตรวจสอบที่เพิ่มมากขึ้น) .. image:: _static/device_key.png | MQTT API จะมีลักษณะการใช้งานเป็นแบบ Publish / Subscribe โดย Publish จะเป็นการส่งข้อมูลไปยัง Topic ที่ต้องการ ส่วน Subscribe จะเป็นการรอรับข้อมูลใน Topic ที่ต้องการ การสั่ง Subscribe Topic ใดก็ตามทำเพียงครั้งเดียวก็จะได้รับข้อมูลใน Topic นั้นไปตลอดจนกว่าจะสั่ง Unsubscribe Topic นั้น หรือการเชื่อมต่อกับ Platform หยุดลง | .. caution:: ควรสั่ง Subscribe Topic ก่อนที่จะมีการสั่ง Publish Topic เดียวกัน เพื่อให้ได้รับข้อมูลที่ถูกส่งมา ซึ่งข้อมูลที่ได้รับจะเป็นข้อมูลที่เกิดจากการ Publish หลังการ Subscribe เท่านั้น | องค์ประกอบสำคัญที่จำเป็นต้องทราบสำหรับการใช้งาน MQTT API คือ Topic เพราะ Publish / Subscribe จำเป็นต้องระบุ Topic ที่ต้องการ Topic จะหน้าที่เหมือน Endpoint บน MQTT Broker เพื่อให้ MQTT Client มาเชื่อมต่อและสื่อสารกัน โดยจะรองรับคุณสมบัติดังต่อไปนี้ - QoS (Quality of Service) 3 ระดับ คือ ข้อตกลงระหว่างผู้ส่ง (Publisher) และผู้รับ (MQTT Broker) ในการรับประกันการส่งข้อมูล **QoS Level 0** : การส่งข้อมูลที่มีการรับประกันผลในระดับต่ำสุด หรือเป็นข้อมูลที่ต้องการความรวดเร็วในการส่ง คือ ไม่ต้องการการตอบกลับว่าข้อมูลถึง MQTT Broker แล้ว **QoS Level 1** : การส่งข้อมูลที่มีการรับประกันผลในระดับที่ทุกครั้งของการส่งข้อมูล ต้องมีการตอบกลับเสมอเพื่อยืนยันว่าข้อมูลได้ส่งไปถึง MQTT Broker แล้ว ถ้าการตอบกลับสูญหาย ผู้ส่งจะทำการส่งข้อมูลไปใหม่จนกว่าจะได้รับการตอบกลับ นั่นหมายความว่า MQTT Broker จะได้รับข้อมูลอย่างน้อย 1 ครั้งแน่นอน แต่ข้อมูลเดียวกันอาจจะได้รับมากกว่า 1 ครั้งด้วยเช่นกัน **QoS Level 2** : การส่งข้อมูลที่มีการรับประกันผลระดับสูงสุด ข้อมูลมีความสำคัญมาก คือ ทุกครั้งของการส่งข้อมูลจะมีการยืนยันว่าถูกส่งไปถึง MQTT Broker อย่างแน่นอนและได้รับข้อมูลครั้งเดียว - Shared Subscription คือ การส่งข้อมูลกระจายไปได้ทุกโหนดที่ Subscribe Topic เดียวกัน - Transparent Virtual Host คือ การ Publish / Subscribe ไปที่ Topic เดียวกัน ถ้า Device อยู่ต่างกลุ่ม ก็จะเหมือนเป็นคนละ Topic กัน | โครงสร้าง Topic ใน |platform_name| Platform สามารถแยกได้เป็น 3 ประเภท ดังนี้ | Message API Topic -------------------- | เป็นการกำหนด Topic สำหรับ Publish / Subscribe ข้อมูลเพื่อสื่อสารระหว่าง Devices ที่อยู่ภายในใต้ Group เดียวกัน โดยรูปแบบการใช้งานให้ขึ้นต้น Topic ด้วย @msg ตามด้วยโครงสร้าง Topic ที่ต้องการ ดังนี้ :publish: ``publish @msg/{any}/{topic}`` :subscribe: ``subscribe @msg/{any}/{topic}`` :ตัวอย่าง Topic: @msg/myhome/bedroom/lamp @msg/sensor/temp @msg/john จะเห็นได้ว่า Topic สามารถระบุเป็นลำดับชั้นได้โดยการคั่นด้วย "/" นอกจากการระบุ Topic ที่เฉพาะเจาะจงแล้ว ยังรองรับการระบุ Topic แบบ Wildcard ด้วย มี 2 ลักษณะ คือ 1. **Wildcard แบบทั้งหมด** หมายถึง การระบุ Topic ตามลำดับชั้้นในส่วนหน้าแล้วปิดท้ายด้วยเครื่องหมาย '#' ตัวอย่างเช่น ================================== ======================================== Publish / Subscribe Topic Publish / Subscribe Topic ที่จะได้รับข้อมูล ================================== ======================================== ``@msg/#`` @msg/{เป็นอะไรก็ได้ กี่ลำดับชั้นก็ได้ มีหรือไม่ก็ได้} เช่น ``@msg/myhome``, ``@msg/myhome/bedroom/lamp``, ``@msg/john`` ``@msg/rooms/#`` @msg/room/{เป็นอะไรก็ได้ กี่ลำดับชั้นก็ได้ มีหรือไม่ก็ได้} เช่น ``@msg/rooms``, ``@msg/rooms/bathroom``, ``@msg/rooms/bedroom/lamp`` ================================== ======================================== 2. **Wildcard แบบเฉพาะชั้น** หมายถึง การระบุ Topic เฉพาะแต่ละลำดับชั้นให้เป็นอะไรก็ได้ โดยแทนด้วยเครื่องหมาย '+' ในลำดับชั้นที่ไม่ต้องการระบุเฉพาะเจาะจง ตัวอย่างเช่น ================================== ======================================== Publish / Subscribe Topic Publish / Subscribe Topic ที่จะได้รับข้อมูล ================================== ======================================== ``@msg/+`` @msg/{เป็นอะไรก็ได้ 1 ลำดับชั้นและต้องมี} เช่น ``@msg/myhome``, ``@msg/temp``, ``@msg/room`` ``@msg/rooms/+`` @msg/room/{เป็นอะไรก็ได้ 1 ลำดับชั้นและต้องมี} เช่น ``@msg/rooms/bathroom``, ``@msg/rooms/bedroom``, ``@msg/rooms/kitchen`` ``@msg/home/+/light`` @msg/home/{เป็นอะไรก็ได้ 1 ลำดับชั้นและต้องมี}/light เช่น ``@msg/home/bathroom/light``, ``@msg/home/livingroom/light``, ``@msg/home/garage/light`` ``@msg/home/+/+/door`` @msg/home/{เป็นอะไรก็ได้ 1 ลำดับชั้นและต้องมี}/{เป็นอะไรก็ได้ 1 ลำดับชั้นและต้องมี}/door เช่น ``@msg/home/john/bedroom/door``, ``@msg/home/upstairs/bathroom/door`` ================================== ======================================== | .. note:: Wildcard Topic - เครื่องหมาย '#' ต้องถูกระบุอยู่ลำดับชั้นท้ายสุดของ Topic เท่านั้น ห้ามมีอะไรต่อท้ายอีก - เครื่องหมาย '#' จะมีการระบุข้อความ Topic จากตำแหน่งนั้นหรือไม่ก็ได้ แต่ เครื่องหมาย '+' บังคับว่าต้องมีการระบุในลำดับชั้นนั้น - เครื่องหมาย '#' และ '+' สามารถใช้ผสมกันได้ แต่ '#' ต้องอยู่ลำดับชั้นท้ายสุดของ Topic เท่านั้น เช่น ``@msg/home/+/bedroom/+/#`` | Shadow API Topic -------------------- | .. image:: _static/shadow_flow.png | MQTT Topic ที่เกี่ยวข้องกับการจัดการ Device Shadow สามารถแยกได้เป็น Publish และ Subscribe โดย Publish จะใช้กรณีที่ต้องการขอข้อมูลหรืออัพเดทข้อมูลใน Device Shadow ส่วน Subscribe จะเป็นการรอรับข้อมูลในกรณีที่มีการ Publish ไปขอข้อมูล หรือในกรณีที่มีการเปลี่ยนข้อมูล Device Shadow และได้ทำการ Subscribe ไว้ ซึ่งการใช้งานจะมีรายละเอียด ดังนี้ 1. **Private Channel Topic** คือ ช่องทางพิเศษสำหรับรับการตอบกลับ (Response) หรือรอรับข้อมูลทุกอย่างที่เกิดขึ้นกับตัวเอง เช่น Device Shadow ตัวเองมีการเปลี่ยนแปลง เป็นต้น โดยรูปแบบการใช้งานให้ขึ้นต้น Topic ด้วย @private มีลักษณะตามนี้ ``@private/{response topic}`` จะมีเพียงการ Subscribe เท่านั้น Response Topic สำหรับ Subscribe @private มีดังนี ====================================== ============================================================ Subscribe Topic คำอธิบาย ====================================== ============================================================ ``@private/#`` การรอรับทุกข้อมูลที่ Publish มายัง Topic ที่ขึ้นต้นด้วย @private/ รวมถึงข่าสารต่างๆ ที่ Platform ต้องการแจ้งให้ทราบก็จะถูก Publish มายัง Topic นี้ ``@private/shadow/data/get/response`` การรอรับ Device Shadow Data เมื่อมีการร้องขอข้อมูลไป ====================================== ============================================================ 2. **Shadow Topic** คือ Topic ที่ใช้สำหรับจัดการ Device Shadow ของตัวเองและของ Device อื่นที่อยู่ภายใต้กลุ่มเดียวกัน โดยถ้าเป็น Device อื่นจะต้องระบุชื่อ (Alias) ของ Device นั้นๆ มีทั้ง Publish (แก้ไขข้อมูล Shadow) และ Subscribe (รอรับข้อมูล Shadow) Topic ที่เกี่ยวข้องมีดังนี้ ========================================================= ================================================== Publish Topic คำอธิบาย ========================================================= ================================================== ``@shadow/data/get`` เป็นการร้องขอข้อมูล Shadow Data ของตัวเองแบบทั้งหมด โดยการรอรับข้อมูลให้ Subscribe Topic ``@private/#`` หรือ ``@private/shadow/data/get/response`` เพื่อรอรับข้อมูล (ใช้ในกรณีที่เป็น Shadow ตัวเองท่านั้น) ``@shadow/data/update`` เป็นการอัพเดทค่าใน Shadow Data โดยส่ง Payload ดังนี้ { "data":{ "field name 1": value 1, "field name 2": value 2, ..., "field name n": value n }} ถ้าต้องการได้รับข้อมูลเมื่อค่าต่าง ๆ ใน Shadow Data ถูกอัพเดทให้ Subscribe Topic ``@shadow/data/updated`` รอไว้ ========================================================= ================================================== .. note:: Publish Topic คือ การส่งข้อความออกไปยัง Topic ตามที่ระบุ Subscribe Topic คือ การขอรับข้อความที่ถูกส่งเข้ามายัง Topic ตามที่ระบุ .. tip:: Publish Topic ``@shadow/data/update`` ในกรณีที่เป็นฟิลด์ที่มีการตั้งค่าใน Device Schema ให้มีการบันทึกลง Timeseries Database ถ้าต้องการกำหนดเวลาของจุดข้อมูลที่บันทึกเอง ให้ใส่ timestamp เข้ามาใน Payload ด้วย ถ้าไม่กำหนดจะเป็นเวลาที่ Server รับข้อมูล ตัวอย่างเช่น MQTT topic : @shadow/data/update MQTT payload : { "data" : { "temp" : 21.5 }, "timestamp": 1566450000000 } โดยมีเงื่อนไขว่า ถ้า timestamp ที่ใส่มานั้น เก่ากว่า timestamp ล่าสุดที่ระบุอยู่ใน Shadow Data ค่าใน Shadow Data จะไม่ถูกอัพเดต และถ้ามีการตั้งค่า Device Trigger ก็จะไม่มี Event Shadow Updated แจ้งออกไป แต่จะแค่ส่งข้อมูลไปเก็บลง Timeseries Database และทำให้เกิดจุดข้อมูลย้อนหลังในเวลาที่กำหนดมาเท่านั้น