最近尝试学习协议适配框架,其中EdgeX作为一款开源的边缘计算平台受到大家的青睐,于是决定一试。目标是实现基于EdgeX的基础的南北MQTT通信功能,整体实现参考了一位大神的博客:

(13条消息) EdgeX 树莓派实践部署_无止无休-CSDN博客_edgex部署https://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.0ports:- "0.0.0.0:48101:48101"container_name: edgex-app-service-configurable-mqtthostname: edgex-app-service-configurable-mqttnetworks:- edgex-networkenvironment:<<: *common-variablesedgex_profile: mqtt-exportService_Host: edgex-app-service-configurable-mqttService_Port: 48101MessageBus_SubscribeHost_Host: edgex-core-dataBinding_PublishTopic: eventsWritable_Pipeline_Functions_MQTTSend_Addressable_Address: 172.17.0.1Writable_Pipeline_Functions_MQTTSend_Addressable_Port: 1883Writable_Pipeline_Functions_MQTTSend_Addressable_Protocol: tcpWritable_Pipeline_Functions_MQTTSend_Addressable_Publisher: edgexWritable_Pipeline_Functions_MQTTSend_Addressable_Topic: EdgeXEventsdepends_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.profilename: "Test.Device.MQTT.Profile"
manufacturer: "Dell"
model: "MQTT-2"
labels:
- "test"
description: "Test device profile"
deviceResources:- name: randfloat32description: "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: randfloat64description: "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: pingdescription: "device awake"properties:value:{ type: "String", size: "0", readWrite: "R", defaultValue: "oops" }units:{ type: "String", readWrite: "R", defaultValue: "" }
-name: messagedescription: "device notification message"properties:value:{ type: "String", size: "0", readWrite: "W" ,scale: "", offset: "", base: ""  }units:{ type: "String", readWrite: "R", defaultValue: "" }deviceCommands:
- name: testrandfloat32get:- { index: "1", operation: "get", deviceResource: "randfloat32"}
- name: testrandfloat64get:- { index: "1", operation: "get", deviceResource: "randfloat64"}
-name: testpingget:- { index: "1", operation: "get", deviceResource: "ping"}
-name: testmessageget:- { index: "1", operation: "get", deviceResource: "message"}set:- { index: "1", operation: "set", deviceResource: "message"}coreCommands:
- name: testrandfloat32get: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: testrandfloat64get: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: testpingget:path: "/api/v1/device/{deviceId}/testping"responses:-code: "200"description: "ping the device"expectedValues: ["ping"]- code: "500"description: "internal server error"expectedValues: []
-name: testmessageget: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: []

树莓派4B+EdgeX+MQTT的填坑之旅相关推荐

  1. React Native填坑之旅--动画篇

    React Native填坑之旅--Button篇 React Native填坑之旅--动画 React Native填坑之旅--HTTP请求篇 动画是提高用户体验不可缺少的一个元素.恰如其分的动画可 ...

  2. 一次动态代理的填坑之旅

    转载自  一次动态代理的填坑之旅 背景 想在现有的接口加上熔断降级或者限流的功能,比较好的方式是通过注解的方式,并基于动态代理进行实现,下面代码是Rhino的实现 @Rhino public clas ...

  3. Jenkins项目实战之-MacOS High Sierra自动化打包方案的填坑之旅

    前面我介绍了如何在android和iOS实现公司内部app的自动化打包构建的过程.这里写一个关于这个app自动化打包平台从想法到实践再到放机房平稳运行的一个回忆录.总的来说,在jenkins上实现an ...

  4. 【填坑之旅】手把手教你如何用AndroidStudio上传自己的library到Jcenter库

    [填坑之旅]手把手教你如何用AndroidStudio上传自己的library到Jcenter库 前言:我们在使用AndroidStudio的时候,会经常用到第三方的代码库.引入第三方库的方式无非就是 ...

  5. 《Getting Started with D3》填坑之旅(六):第三章(下)

    Chapter 3. Scales, Axes and Lines(比例尺.坐标轴与线) (接上篇:<Getting Started with D3>填坑之旅(五):第三章(上)) 示例2 ...

  6. AppCode Updating indexes一直不停的填坑之旅

    最近在做APP安装包瘦身,找到了传说中的AppCode神器. AppCode 提供了 Inspect Code 来诊断代码,其中含有查找无用代码的功能.它可以帮助我们查找出 AppCode 中无用的类 ...

  7. 关于Echarts的填坑之旅

    正如标题所说,这是Echarts的一遍填坑,如果你是一些echart的配置的话可以阅读 http://echarts.baidu.com/opti...的官网配置信息.今天我想给大家分享的是一些我前段 ...

  8. 微信云托管-填坑之旅

    微信云开发开始收费了,一个月20块钱,贼贵,用不起.而按用量收费.资源还能复用的兄弟产品微信云托管还像还行.所以就有了一场填坑旅行. windows10下安装docker之坑 在本地开发,需要使用do ...

  9. ViewPager中显示图片和播放视频填坑之旅

    一.需求来源与实现思路 1.最近项目需求中有用到需要在ViewPager中播放视频和显示图片的功能,视频是本地视频,最开始的实现思路是ViewPager中根据当前item位置对应的是图片还是视频去初始 ...

最新文章

  1. Kali Linux 2020.1快速修改root用户密码
  2. Android移动开发之【Android实战项目】在Service中弹出Dialog对话框,即全局性对话框
  3. Linux命令:MySQL系列之十一--MySQL日志管理
  4. 十进制小数化为二进制小数的方法是什么_十进制转成二进制的两种方式
  5. 小米android停止,小米由于错误而停止将Android 10推广到MiA3
  6. 使用 bind 搭建DNS 服务器
  7. linux小白-基础命令-cd
  8. Sublime Text 3.1 3170正式版+Patch注册机
  9. jq获取页面高度_JQuery获取页面高度宽度
  10. 【PMP认证考试之个人总结】第 3 章 项目整合管理
  11. 终结VC2005分发包版本问题
  12. android apk 在线分析,apkanalyzer
  13. 暗黑2魔电西格玛攻略_听说你想刷爆怪物的狗头?或许可以试试《暗黑破坏神》类单机手游...
  14. zxing扫描二维码和识别图片二维码及其优化策略
  15. 知道ip获取计算机密码,知道iP地址怎么获取密码
  16. 没用完的手机流量是否清零?讨论+吐槽
  17. android仿简书编辑器,自己写一个类似知乎编辑器的编辑器(3)
  18. SpringBoot项目中自动加载datasourceConfig配置导致启动失败
  19. 【好书推荐】第一本无人驾驶技术书
  20. java获取三个数从小到大排序_三个数从小到大排序

热门文章

  1. DUI lib学习总结
  2. nlp技能,jieba分词
  3. c++ [Error] conflicting declaration的错误
  4. Android软件开发面试题,Android入门
  5. 《跨语言文本相似性检测》第一周—前期调研
  6. 小球自由落体_自由落体瀑布
  7. 计导 第 10 章 软件工程
  8. Nexus概述- Nexus 简介、安装管理操作
  9. 手机号码如何检测开通微信
  10. Incarnation概念