前言:
本文来自对edgex实际操作的记述以及对edgexfoundry的部分原文翻译和对文档的理解,已务求描述的准确性和可操作性,如有错误或建议请留言。
开发文档原文请参阅:[https://github.com/edgexfoundry/edgex-docs/ 此官方文档更新比较差,实际操作会有问题,仅用来做理解性参考是可以的]
边缘计算的开源框架比较多,比较有代表性的是针对物联网设备服务的edgexfoundry,以及针对云的能力扩展的kubeedge。
这两个项目都是开源的,采用golang进行开发。
edgexfoundry的源代码:https://github.com/edgexfoundry/edgex-go
kubeedge的源代码:https://github.com/kubeedge/kubeedge
1、EdgeX的运行方式之一:采用docker,docker-compose
注:这里假定docker,docker-compose都已安装好。需要注意docker-compose需要是较新的版本,否则后面docker-compose.yml的语法可能不支持,会报错。
1.1 新建一个目录如edgex
mkdir edgex_docker
1.2 下载该文件:
wget https://raw.githubusercontent.com/edgexfoundry/developer-scripts/master/releases/edinburgh/compose-files/docker-compose-edinburgh-1.0.1.yml
并另存为: docker-compose.yml
1.3 执行命令下载镜像 :
docker-compose pull
1.4 执行命令启动edgex微服务(如果后台有mongod进程,该服务需要提前停掉,否则运行失败):
docker-compose up -d
1.5 执行命令查看启动的微服务:
docker-compose ps
记住微服务提供服务的端口号比较重要,有利于后续操作理解,是在操作那个服务的api。
另外通过访问consul[edgex的服务注册组件],可以看到已注册的服务。
2、EdgeX的运行方式之二:直接编译源码启动
EdgeX的编译依赖zeromq(微服务组件默认的通讯方案),需要提前安装;
运行时需要mangodb,需要提前安装,否则运行会报错。
2.1 下载源码
git clone git@github.com:edgexfoundry/edgex-go.git
2.2 编译
cd edgex-go
make build
可以看到,所有编译完的微服务位于edgex-go/cmd目录。
2.3 运行
make run
或者
cd bin
./edge-launch.sh
在这里预留一个问题,在采用方式二运行时【EdgeX的运行方式之二:直接编译源码启动】并没有启动consul,但服务仍然可以正常运行,原因待后续分析【可能有默认的机制】。
3、用edgex连接一个设备(随机数发生器)
有两种方式运行该设备
3.1 源码运行
源码能址:git clone https://github.com/edgexfoundry/device-random
下载后执行 make,编译完成的可执行文件在cmd目录,可以直接运行。需要注意的是,如果是源码编译直接运行,需要edgex本身也采用二进制代码运行的方式(EdgeX的运行方式之二:直接编译源码启动),否则可能由于网络配置原因导致服务连接失败。
3.2 容器运行
修改edgex_docker下的docker-compose.yml文件,去掉下列内容的注释:
device-random:
image: edgexfoundry/docker-device-random-go:1.0.1
ports:
- "49988:49988"
container_name: edgex-device-random
hostname: edgex-device-random
networks:
- edgex-network
volumes:
- db-data:/data/db
- log-data:/edgex/logs
- consul-config:/consul/config
- consul-data:/consul/data
depends_on:
- data
- command
然后再执行:
docker-compose up -d
可以在consul后台,发现多了一个服务:
这个设备容器可能运行错误,通过docker-compose logs device-random 查到可能是数据库数据冲突问题[原始mangodb镜像中有数据]。可以登录mongodb,删除coredata,metadata表之后,可以运行正常。
3.3 查询新增设备信息
在终端执行:
curl http://localhost:48080/api/v1/event/device/Random-Integer-Generator01/10
可以查询到设备信息。48080是core-data的服务端口。
推荐使用Postman查询,可以得到结构化数据:
4 转发设备消息到一个云应用(以MQTT Broker为例)
本例通过48071(export_client)注册一个客户端,转发消息到一个MQTT Broker,本例采用HiveMQ(这是一个公开的可访问的MQTT Broker),类似的MQTT Broker比较多,如mosquitto, EMQ,HMQ等。
在终端执行下列指令:
curl -X POST -d '{
"name":"QuickStartExportSMG",
"addressable":{
"name":"HiveMQBroker",
"protocol":"tcp",
"address":"broker.hivemq.com",
"port":1883,
"publisher":"EdgeXExportPublisher",
"topic":"EdgeXQuickStartGuideSMG"
},
"format":"JSON",
"filter":{
"deviceIdentifiers":["Random-Integer-Generator01"]
},
"enable":true,
"destination":"MQTT_TOPIC"
}' http://localhost:48071/api/v1/registration
然后打开一个MQTT client连接broker.hivemq.com,订阅EdgeXQuickStartGuideSMG主题。本例通过一个mqtt的web客户端来定阅,其地址为:http://www.hivemq.com/demos/websocket-client/
完成定阅后,将会持续性收到随机数发生器发送的消息:
采用mosquitto可以完成相同的消息定阅:
mosquitto_sub -h broker.hivemq.com -p 1883 -t EdgeXQuickStartGuide
5、控制这个设备
设备注册到edgex时,需要提供一个device profile,这是一个文本描述,描述了从设备读取数据的方式,也描述了对设备的操控的方法。
上述例子中注册的随机数发生器Random-Integer-Generator01也在注册时提供了一个device profile,这个profile定义了读数据的有效范围,以及对设备控制的一些指令描述。
5.1 通过core-command(48082)来查询设备的可用指令
curl http://localhost:48082/api/v1/device/name/Random-Integer-Generator01
(建议通过Postman)
{
"id": "ca1caf0c-dfa7-4ac8-bee3-8dfcd1df32f9",
"name": "Random-Integer-Generator01",
"adminState": "UNLOCKED",
"operatingState": "ENABLED",
"lastConnected": 0,
"lastReported": 0,
"labels": [
"device-random-example"
],
"location": null,
"commands": [
{
"created": 1573721988576,
"modified": 1573721988576,
"id": "f0d0f546-e3a6-4808-99a1-1b3f3012df4f",
"name": "GenerateRandomValue_Int8",
"get": {
"path": "/api/v1/device/{deviceId}/GenerateRandomValue_Int8",
"responses": [
{
"code": "503",
"description": "service unavailable"
}
],
"url": "http://edgex-core-command:48082/api/v1/device/ca1caf0c-dfa7-4ac8-bee3-8dfcd1df32f9/command/f0d0f546-e3a6-4808-99a1-1b3f3012df4f"
},
"put": {
"path": "/api/v1/device/{deviceId}/GenerateRandomValue_Int8",
"parameterNames": [
"Min_Int8",
"Max_Int8"
],
"url": "http://edgex-core-command:48082/api/v1/device/ca1caf0c-dfa7-4ac8-bee3-8dfcd1df32f9/command/f0d0f546-e3a6-4808-99a1-1b3f3012df4f"
}
},
{
"created": 1573721988593,
"modified": 1573721988593,
"id": "06bf3bad-4040-44d2-a62a-7dd867dcdb62",
"name": "GenerateRandomValue_Int16",
"get": {
"path": "/api/v1/device/{deviceId}/GenerateRandomValue_Int16",
"responses": [
{
"code": "503",
"description": "service unavailable"
}
],
"url": "http://edgex-core-command:48082/api/v1/device/ca1caf0c-dfa7-4ac8-bee3-8dfcd1df32f9/command/06bf3bad-4040-44d2-a62a-7dd867dcdb62"
},
"put": {
"path": "/api/v1/device/{deviceId}/GenerateRandomValue_Int16",
"parameterNames": [
"Min_Int16",
"Max_Int16"
],
"url": "http://edgex-core-command:48082/api/v1/device/ca1caf0c-dfa7-4ac8-bee3-8dfcd1df32f9/command/06bf3bad-4040-44d2-a62a-7dd867dcdb62"
}
},
{
"created": 1573721988593,
"modified": 1573721988593,
"id": "c9f02fe1-1311-4e9a-8dbb-09e39bc45711",
"name": "GenerateRandomValue_Int32",
"get": {
"path": "/api/v1/device/{deviceId}/GenerateRandomValue_Int32",
"responses": [
{
"code": "503",
"description": "service unavailable"
}
],
"url": "http://edgex-core-command:48082/api/v1/device/ca1caf0c-dfa7-4ac8-bee3-8dfcd1df32f9/command/c9f02fe1-1311-4e9a-8dbb-09e39bc45711"
},
"put": {
"path": "/api/v1/device/{deviceId}/GenerateRandomValue_Int32",
"parameterNames": [
"Min_Int32",
"Max_Int32"
],
"url": "http://edgex-core-command:48082/api/v1/device/ca1caf0c-dfa7-4ac8-bee3-8dfcd1df32f9/command/c9f02fe1-1311-4e9a-8dbb-09e39bc45711"
}
}
]
}
注意:url中的deviceid和commandid是不同的,是edgex自动生成的。
get描述了读设备内容的方法。
put描述了写设备的操作方法。
5.2 对设备的读操作
curl http://localhost:48082/api/v1/device/5c0e8a259f8fc20001a5d230/command/5c0e8a259f8fc20001a5d22b
读操作会返回:
{
"device": "Random-Integer-Generator01",
"origin": 1573722396641,
"readings": [
{
"origin": 1573722396640,
"device": "Random-Integer-Generator01",
"name": "RandomValue_Int8",
"value": "66"
}
]
}
5.3 对设备的控制操作
curl -X PUT -d '[
{"Min_Int8": "0", "Max_Int8": "50"}
]' http://localhost:48082/api/v1/device/ca1caf0c-dfa7-4ac8-bee3-8dfcd1df32f9/command/f0d0f546-e3a6-4808-99a1-1b3f3012df4f
执行上述指令后,会把随机数生成器的生成范围从默认的-128至127,修改为0至50;
6 总结
通过一些简单的操作可以看出
1、edgex采用consul做服务注册、发现;采用mongodb(可替换)做数据及配置存贮;采用zeromq做消息中间件。
2、edgex是一组微服务(基础服务),每个微服务都独立提供http形式的api供外部调用,微服务组件之间有互相调用关系。
3、应用基于edgex的api和数据定义做二次开发,应用也是一个微服务组件(可以分为设备接入应用和功能应用)。