本文为Edgex系列第四篇文章,本次我们从零开始接入一个MQTT虚拟设备,体验一个完整的接入流程,并使用相关服务API进行调用。
js
脚本作MQTT Device
;mosquitto
作代理,类似于MQ
的broker
;client
使用EdgeX
内置的device-mqtt-go模块,当然这里我们也可以基于EdgeX的SDK进行自定义开发。MQTT Device simulation发布DataTopic
和ResponseTopic
,接受来自CommandTopic
的请求。
创建目录与文件。
- custom-config
|- profiles
|- my.custom.device.profile.yml
|- devices
|- my.custom.device.config.toml
复制代码
编辑profile文件:vim my.custom.device.profile.yml ,内容如下
name: "my-custom-device-profile"
manufacturer: "iot"
model: "MQTT-DEVICE"
description: "Test device profile"
labels:
- "mqtt"
- "test"
deviceResources:
-
name: randnum
isHidden: true
description: "device random number"
properties:
valueType: "Float32"
readWrite: "R"
-
name: ping
isHidden: true
description: "device awake"
properties:
valueType: "String"
readWrite: "R"
-
name: message
isHidden: false
description: "device message"
properties:
valueType: "String"
readWrite: "RW"
deviceCommands:
-
name: values
readWrite: "R"
isHidden: false
resourceOperations:
- { deviceResource: "randnum" }
- { deviceResource: "ping" }
- { deviceResource: "message" }
复制代码
编辑config文件:vim my.custom.device.config.toml ,内容如下
# Pre-define Devices
[[DeviceList]]
Name = "my-custom-device"
ProfileName = "my-custom-device-profile"
Description = "MQTT device is created for test purpose"
Labels = [ "MQTT", "test" ]
[DeviceList.Protocols]
[DeviceList.Protocols.mqtt]
CommandTopic = "CommandTopic"
[[DeviceList.AutoEvents]]
Interval = "30s"
OnChange = false
SourceName = "message"
复制代码
这里的CommandTopic用于处理GET/SET请求。
make gen ds-mqtt mqtt-broker no-secty ds-virtual ui
生成docker-compose文件,这里mqtt-broker
即是mosquitto
,ds-mqtt
即是device-mqtt-go
cat docker-compose.yml
,删除端口映射前的127.0.0.1
device-mqtt
环境变量与数据卷EdgeX Foundry
device-mqtt:
...
environment:
...
DEVICE_DEVICESDIR: /custom-config/devices
DEVICE_PROFILESDIR: /custom-config/profiles
...
volumes:
- /usr/local/cq/tool/custom-config:/custom-config
复制代码
docker-compose.yml
文件目录执行 docker-compose up -d
docker ps
检查服务是否都已经启动注:红线处的导出服务大家可以先不用考虑。
mock-device.js
文件vim mock-device.js
function getRandomFloat(min, max) {
return Math.random() * (max - min) + min;
}
const deviceName = "my-custom-device";
let message = "test-message";
// DataSender sends async value to MQTT broker every 15 seconds
schedule('*/15 * * * * *', ()=>{
let body = {
"name": deviceName,
"cmd": "randnum",
"randnum": getRandomFloat(25,29).toFixed(1)
};
publish( 'DataTopic', JSON.stringify(body));
});
// CommandHandler receives commands and sends response to MQTT broker
// 1. Receive the reading request, then return the response
// 2. Receive the set request, then change the device value
subscribe( "CommandTopic" , (topic, val) => {
var data = val;
if (data.method == "set") {
message = data[data.cmd]
}else{
switch(data.cmd) {
case "ping":
data.ping = "pong";
break;
case "message":
data.message = message;
break;
case "randnum":
data.randnum = 12.123;
break;
}
}
publish( "ResponseTopic", JSON.stringify(data));
});
复制代码
docker run -d --restart=always --name=mqtt-scripts \
-v /usr/local/cq/tool/mqtt-scripts:/scripts \ dersimn/mqtt-scripts
--url mqtt://172.17.0.1 --dir /scripts
复制代码
注意将/usr/local/cq/tool/mqtt-scripts
替换为宿主机文件路径。运行结束后使用docker ps
检查服务是否启动。
进入${EdgexIp}:4000
可以看到一个关联设备,我们点击之后进入
command
表示物模型中定义的get/set
方法,
auto events
表示定时任务,即30s会执行一次message资源,OnChange为false代表,数据没有变化依旧上报。 正在上传…重新上传取消
然后我们查看DataCentor是否有数据进来
另外我们也可以通过HTTP调用相关服务获取数据,如我们调用设备服务,查看所有服务信息
我们可以看到服务都已经注册上来了。
下一篇介绍数据的导出。
github.com/edgexfoundr… docs.edgexfoundry.org/2.0/example…