在kubernetes的環境下,MQTT broker的選擇有HiveMQ、EMQX、Mosquitto等,或者使用三大雲端服務各自提供的自建MQTT broker,比如我們這邊最終,就選擇使用Greengrass來實踐MQTT的架構。
在完成Greengrass與edge device溝通之前,我們會以docker(container base)來試驗雲端與地端是否能準確溝通。有關Greengrass的基礎設定,可以參考這篇文章,這裡不再贅述。
只補充對於Greengrass的一些優缺點分析:
但目前因Greengrass在後續元件的修改符合我客製化的情況,遇到許多issues,我最終決定在POC的實驗上,先行使用Mosquitto架設於一台雲端VM上。
先開啟一台VM,然後逐步架設Mosquitto,是為mqtt server。
而client端是透過websocket與mqtt server連接,使用js mqtt library。
const client = mqtt.connect('ws://ACCOUNT_ID:ACCOUNT_PASSWORD@MQTT_IP_ADDRESS:MQTT_PORT', {
clientId: new Date().getTime()
});
client.on('connect', function() {
console.log('connected!');
client.subscribe('scan');
client.publish('iot_clicked_point', payload);
});
local server端則透過paho的mqtt client與mqtt server連接。
self.client = mqtt.Client()
self.client.on_connect = self.on_connect
self.client.on_message = self.subscribe_from_iot
self.client.username_pw_set(ACCOUNT_ID,ACCOUNT_PASSWORD)
self.client.connect(MQTT_IP_ADDRESS, MQTT_PORT, 60)
local server透過rclpy create一個ros node subscribe與publish ros topic,並將從edge device(小車)subscribe收到的topics資料透過paho的mqtt client傳給mqtt server;
self.create_subscription(message_type, ros_topic.strip(), publish_to_iot, 1)
#publish_to_iot的內容
self.client.publish(topic, str(telemetry_data))
以及透過mqtt client監聽來自mqtt傳送過來的訊息,並透過rclpy publish給edge device。
#以下是subscribe_from_iot的內容
pub_msg = PointStamped()
pub_msg.header.stamp = self.get_clock().now().to_msg()
pub_msg.header.frame_id = "map"
if "point" in data:
pub_msg.point.x = float(data['point']['x'])
pub_msg.point.y = float(data['point']['y'])
pub_msg.point.z = float(data['point']['z'])
self.ros_publishers[msg.topic].publish(pub_msg)
mqtt上的server另外有一隻python程式,負責subscribe要存放至雲端資料庫dynamodb的程式(使用python boto3 library)。
用圖形來表示的話,整個從web端到mqtt到落地edge device的架構流程如下: