日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

樹莓派4B+EdgeX+MQTT的填坑之旅

作者:屁屁張 更新時間: 2021-12-06 編程語言

最近嘗試學習協議適配框架,其中EdgeX作為一款開源的邊緣計算平臺受到大家的青睞,于是決定一試。目標是實現基于EdgeX的基礎的南北MQTT通信功能,整體實現參考了一位大神的博客:

(13條消息) EdgeX 樹莓派實踐部署_無止無休-CSDN博客_edgex部署icon-default.png?t=LA92https://blog.csdn.net/bxjie/article/details/113860800由于大神寫的比較高階,作為小白的我踩了不少坑,下面分享給大家,僅供參考。


硬件

Raspberry Pi 4 Model B?

不一定非要最新的,不同的硬件版本配套不同的操作系統及其他軟件安裝版本

?microSD卡 128GB

沒必要買很大,主要看需求。最好不要低于8G

micro轉HDMI轉接頭

由于本人比較懶不想安遠程控制軟件,于是必須有個連接顯示屏的轉接頭,具體規格因顯示屏而異

鍵盤、讀卡器、鼠標、電源線(TypeC)、顯示屏


軟件

1.?格式化存儲卡

先用SD格式化軟件格式化存儲卡,如果后面安裝出現問題(比如:安錯系統,別問我怎么知道的...)想清空存儲卡可以先SD格式化再用diskgenius軟件恢復存儲卡系統分區。這部分網上很多參考,也很簡單。

2.?安裝arm64位操作系統

Index of /raspios_arm64/images/raspios_arm64-2021-05-28

下載.zip文件即可。

3.?燒錄系統

燒錄軟件也有很多選擇,我用的是官網的:

Raspberry Pi OS – Raspberry Pi

?至此燒錄完成。

?4.?初始化樹莓派

第一次使用的話會有一些設置選擇,可參考:

樹莓派4B開門教程HDMI連接顯示器 - 知乎

?如果想安裝一個中文輸入法,可參考:

樹莓派入門(八)—— 漢化Raspbian操作系統_bigmarshal的博客-CSDN博客_樹莓派漢化

輸入法需要reboot之后才生效。

5.?搭建EdgeX

按照大神的步驟可以開始搭建EdgeX了,為了整體流暢性,下面有一些步驟直接拷貝大神的

5.1 安裝docker-ce

$curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/raspbian/gpg | sudo apt-key add -

獲取docker-ce安裝包,下載下面三個文件并離線安裝:
https://download.docker.com/linux/debian/dists/buster/pool/edge/arm64/

$sudo dpkg -i containerd.io_1.3.7-1_arm64.deb  
$sudo dpkg -i docker-ce-cli_19.03.13_3-0_debian-buster_arm64.deb
$sudo dpkg -i docker-ce_19.03.13_3-0_debian-buster_arm64.deb  

設置docker鏡像:

$sudo cat /etc/docker/daemon.json 
{
        "registry-mirrors": ["http://hub-mirror.c.163.com"]
}

$sudo systemctl daemon-reload
$sudo systemctl restart docker

5.2 安裝docker-compose

$sudo apt-get install libffi-dev 
$sudo apt-get install openssl
$pip3 install --default-timeout=100000 docker-compose

5.3 EdgeX搭建

根據官網的命令可以quick-start:

Quick Start - EdgeX Foundry Documentation

$curl https://raw.githubusercontent.com/edgexfoundry/developer-scripts/master/releases/geneva/compose-files/docker-compose-geneva-redis-no-secty-arm64.yml -o docker-compose.yml

此時報錯:

?直接搜索報錯內容說docker-compose沒有安裝成功,于是嘗試大神的解決方法:

$pip3 install --upgrade --default-timeout=100000 docker-compose -i http://pypi.douban.com/simple

出現新的錯誤:

?這樣看是python版本不夠,不匹配pysistent。先嘗試升級python,遇到如下問題:

"sudo: /etc/sudoers is world writable\r\nsudo: no vaild sudoers sources found,quitting"

檢索錯誤后發現原來是因為在安裝docker鏡像時為了寫入json文件和解決DNS污染問題而重寫入hosts中的raw.githubusercontent.com的IP地址(前面遇到的一個問題),而使得牽一發而動全身。解決方法:

$pkexec chmod0440 /etc/sudoers

當我以為可以簡簡單單升級python時,天真了...

?升級也費勁,同時發現pyrsistent竟然沒有,于是反向思維指定pyrsistent版本,并查看docker是否安裝,發現新的錯誤:

docker.errors.DockerException:Error while fetching server API version:('Connection aborted'......

原因是docker_runner 沒有docker的運行權限,解決方案:

vi /etc/group
...
docker:x:123:gitlab-runner
gitlab-runner:x:122:
...

至此,剛把獲取docker-compose.yml文件的命令的坑填好...

下面進行EdgeX UI可視化,同時添加device-mqtt微服務.

在docker_compose文件中有注釋mqtt,同時沒有ui命令, 需要取消相應注釋,同時補充ui。參考大神的圖片:

本機輸入localhost:4000/可以看到前端展示了,登錄用本機賬戶和密碼即可。

?5.4 啟動微服務

這一部分分為三個步驟:

1)北向基于 app-service-mqtt 實現 EdgeXCore 的 device-random 服務

2)南向基于 DeviceDemo 模擬設備發送數據報文

3)南北打通

流程圖照搬大神的:

5.4.1 北向打通

這一步算是基礎,因為后面的很多實現步驟都類似,而且也是理解整體業務流程的第一步,所以值得好好琢磨一下。

首先安裝mosquitto:

 $sudo apt-get install mosquitto
 $sudo apt-get install mosquitto-clients

配置微服務,可以新建一個docker-compose-less.yml,也可以在原來的yml文件里面粘貼。

app-service-mqtt:
    image: edgexfoundry/docker-app-service-configurable-arm64:1.2.0
    ports:
      - "0.0.0.0:48101:48101"
    container_name: edgex-app-service-configurable-mqtt
    hostname: edgex-app-service-configurable-mqtt
    networks:
      - edgex-network
    environment:
      <<: *common-variables
      edgex_profile: mqtt-export
      Service_Host: edgex-app-service-configurable-mqtt
      Service_Port: 48101
      MessageBus_SubscribeHost_Host: edgex-core-data
      Binding_PublishTopic: events
      Writable_Pipeline_Functions_MQTTSend_Addressable_Address: 172.17.0.1
      Writable_Pipeline_Functions_MQTTSend_Addressable_Port: 1883
      Writable_Pipeline_Functions_MQTTSend_Addressable_Protocol: tcp
      Writable_Pipeline_Functions_MQTTSend_Addressable_Publisher: edgex
      Writable_Pipeline_Functions_MQTTSend_Addressable_Topic: EdgeXEvents
    depends_on:
      - consul
      - data

啟動mqtt broker(默認port:1883):

$sudo mosquitto -v

啟動mqtt微服務:

$sudo docker-compose -f docker-compose-less.yml up app-service-mqtt

啟動MQTT訂閱者:

$sudo mosquitto_sub -h 127.0.0.1 -p 1883 -t EdgeXEvents

5.4.2 南向打通

安裝golang環境,網上資料很多。

下載device demo程序:

$git clone https://github.com/edgexfoundry/device-mqtt-go

device demo需要修改的地方如下:

const (
?? ?brokerUrl ?= "127.0.0.1"
?? ?brokerPort = 1883
?? ?username ? = "admin"
?? ?password ? = "public"
)


func runCommandHandler() {
?? ?var mqttClientId = "DeviceCommandSubscriber"
?? ?var qos = 0
?? ?var topic = "CommandTopic"


func runDataSender() {
?? ?var mqttClientId = "DeviceIncomingDataPublisher"
?? ?var qos = byte(0)
?? ?var topic = "DataTopic"

?? ?uri := &url.URL{
?? ??? ?Scheme: "tcp",
?? ??? ?Host: ? fmt.Sprintf("%s:%d", brokerUrl, brokerPort),
?? ??? ?User: ? url.UserPassword(username, password),
?? ?}

?? ?client, err := createMqttClient(mqttClientId, uri)
?? ?defer client.Disconnect(5000)
?? ?if err != nil {
?? ??? ?fmt.Println(err)
?? ?}

?? ?var data = make(map[string]interface{})
?? ?data["name"] = "device_name_1"
?? ?data["cmd"] = "randfloat32"
?? ?data["method"] = "get"

?? ?for {
?? ??? ?data["randfloat32"] = rand.Float64()
?? ??? ?jsonData, err := json.Marshal(data)
?? ??? ?if err != nil {
?? ??? ??? ?fmt.Println(err)
?? ??? ?}
?? ??? ?client.Publish(topic, qos, false, jsonData)

?? ??? ?fmt.Println(fmt.Sprintf("Send response: %v", string(jsonData)))

?? ??? ?time.Sleep(time.Second * time.Duration(15))
?? ?}

}

?編譯device.go

go build
./mock

下載配置文檔 mqtt.test.device.profile.yml(博客最后給出文件)

在UI和consul上設置參數(見大神博客)

5.4.3 南北打通

啟動兩個mqtt broker,以防之前的端口被占用,先查看一下:

ps -ef | grep mosquitto

如果有MQTT被占用,則kill it IPD

分別啟動1883和1884的mqtt broker:

$sudo mosquitto -v
$sudo mosquitto -v -p 1884

啟動docker-compose,并關閉device-random微服務,并檢查容器此時開啟的服務

$sudo docker-compose up -d
$sudo docker stop edgx-device-random
$sudo docker-compose ps

啟動北向app-service-mqtt以及mqtt訂閱者,注意此時的docer-compose里面的app-service-mqtt的port需要改為:1884

$sudo docker-compose -f docker-compose-less.yml up app-service-mqtt
$sudo mosquitto_sub -h 127.0.0.1 -p 1884 -t EdgeXEvents

啟動南向:

go build
./mock

如果想查看docker中mqtt微服務的運行情況?,可執行:

$sudo docker-compose up device-mqtt

在UI上的配置操作和前面一樣,同樣參考大神博客即可,顯擺一張成功操作界面:)

命令行窗口的南北成功連接狀態也可參考大神博客,下面是我的一些隨便截圖:

?至此,基于EdgeX的簡單南北MQTT搭建成功~~歡迎一起探討~~


##mqtt.test.device.profile

name: "Test.Device.MQTT.Profile"
manufacturer: "Dell"
model: "MQTT-2"
labels:
- "test"
description: "Test device profile"
deviceResources:

- name: randfloat32
  description: "device random number with Base64 encoding"
  properties:
    value:
      { type: "Float32", size: "4", readWrite: "R", defaultValue: "0.00", minimum: "100.00", maximum: "0.00", floatEncoding: "Base64" }
    units:
      { type: "String", readWrite: "R", defaultValue: "" }
- name: randfloat64
  description: "device random number with e notion"
  properties:
    value:
      { type: "Float64", size: "4", readWrite: "R", defaultValue: "0.00", minimum: "100.00", maximum: "0.00", floatEncoding: "eNotation" }
    units:
      { type: "String", readWrite: "R", defaultValue: "" }
-
  name: ping
  description: "device awake"
  properties:
    value:
      { type: "String", size: "0", readWrite: "R", defaultValue: "oops" }
    units:
      { type: "String", readWrite: "R", defaultValue: "" }
-
  name: message
  description: "device notification message"
  properties:
    value:
      { type: "String", size: "0", readWrite: "W" ,scale: "", offset: "", base: ""  }
    units:
      { type: "String", readWrite: "R", defaultValue: "" }

deviceCommands:
- name: testrandfloat32
  get:
    - { index: "1", operation: "get", deviceResource: "randfloat32"}
- name: testrandfloat64
  get:
    - { index: "1", operation: "get", deviceResource: "randfloat64"}
-
  name: testping
  get:
    - { index: "1", operation: "get", deviceResource: "ping"}
-
  name: testmessage
  get:
    - { index: "1", operation: "get", deviceResource: "message"}
  set:
    - { index: "1", operation: "set", deviceResource: "message"}

coreCommands:
- name: testrandfloat32
  get:
    path: "/api/v1/device/{deviceId}/testrandfloat32"
    responses:
    -
      code: "200"
      description: "get the random float32 value"
      expectedValues: ["randfloat32"]
    - code: "500"
      description: "internal server error"
      expectedValues: []
- name: testrandfloat64
  get:
    path: "/api/v1/device/{deviceId}/testrandfloat64"
    responses:
      - code: "200"
        description: "get the random float64 value"
        expectedValues: ["randfloat64"]
      - code: "500"
        description: "internal server error"
        expectedValues: []
-
  name: testping
  get:
    path: "/api/v1/device/{deviceId}/testping"
    responses:
    -
      code: "200"
      description: "ping the device"
      expectedValues: ["ping"]
    - code: "500"
      description: "internal server error"
      expectedValues: []
-
  name: testmessage
  get:
    path: "/api/v1/device/{deviceId}/testmessage"
    responses:
    -
      code: "200"
      description: "get the message"
      expectedValues: ["message"]
    - code: "500"
      description: "internal server error"
      expectedValues: []
  put:
    path: "/api/v1/device/{deviceId}/testmessage"
    parameterNames: ["message"]
    responses:
    -
      code: "204"
      description: "set the message."
      expectedValues: []
    - code: "500"
      description: "internal server error"
      expectedValues: []

原文鏈接:https://blog.csdn.net/m0_61835993/article/details/122129914

欄目分類
最近更新