技术标签: 边缘计算
本文为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…
[问题描述]:随机区间的划分,有兴趣可以考虑一下问题: 将长度位len的区间划分成n段,每一段的长度是0~m的一个随机值.(len,n,m是给定的值,并n*m>len).或者可以描述为: 产生一个数列使其满足一下要求(len,n,m是给定的值,并n*m>len): 1、数列有n项; 2、数列的每一项使0~m的一个随机值; 3、此数列的各项之和是len;_matlab把区间分成若干份
欢迎来到Altaba的博客…redis是非常好用的中间件数据库,可以在频繁操纵数据库时候起到非常大的优化作用,我在使用后端做即时通讯聊天功能时候,利用了redis做消息缓存,简直真香警告!建议初学者都可以去熟悉下redis以下是常见的nodejs 中使用redis,使用简单,欢迎查阅首先安装 npm install redis --savedemovar redis = require..._nodejs redis 判断key是否存在
想要"决战人工智能"就必须要了解人工智能的程序,用计算机编成交易策略进行自动下单交易。小编下来带大家了解一下当前我国程序化发展情况、国内程序化平台、程序化的优势与缺点、懂金融、懂程序化的复合型人才—— “未来金融市场上的‘金饭碗’”决战人工智能决战人工智能一、当前我国程序化发展情况程序化或许对于一些朋友来说,它算是一个新名词。但其实它在我国已经有多年的发展历史。国内最早的程序化是基于文华财经..._wh6可以编程
1.最懒的方法——Nearest Neighbor对于三角形内的点,离三个顶点谁最近,就赋值为那个顶点对应的颜色。2.最天真的方法——Distance三角形内一点的值应该来自于三个顶点。计算距离:定义权重:颜色表示为权重的平均:总而言之,我们通过三角形每个顶点到点P的距离来混合定点颜色,从而定义点P的插值颜色。这个方法简单,易于实现,而且相当直观,在一些应用中表现良好..._三角形插值
文章目录11.01实现思路Code12.06实现思路Code12.08实现思路12.11实现思路Code11.01实现思路Code12.05实现思路Code运行结果12.06实现思路Code12.08实现思路12.11实现思路Code运行结果11.01实现思路子类可以继承父类的方法,如果覆盖了则需要创建父类对象来调用(如父类的toString());在之类中可以用super调用父类的方法....
这篇文章目的是让初学者利用SQL注入技术来解决他们面临的问题, 成功的使用它们,并在这种攻击中保护自己。 1.0 介绍 当一台机器只打开了80端口, 你最依赖的漏洞扫描器也不能返回任何有用的内容, 并且你知道管理员经常为机器打补丁, 我们就不得不使用web攻击方式了. SQL注入是web攻击的一种类型 ,这种方式只需要开放80端口就够了并且即使管理员打了全部的补丁也能工作. 它攻击的...
procedure EnumFileInQueue(path: PChar; fileExt: string; fileList: TStringList);var searchRec: TSearchRec; found: Integer; tmpStr: string; curDir: string; dirs: TQueue; pszDir: PChar;begin dirs := TQueue.Create; //创建目录队列 _delphi加载文件夹文件并按名称排序
python毕业设计作品基于django框架 校园失物招领系统毕设成品(7)中期检查报告_校园失物招领系统django
实现方法:1.在登录验证的 Controller 里面调用私有函数 addCookie 。 @RequestMapping(value="/loginValidate")public String loginValidate(HttpServletRequest request, HttpServletResponse response) throws IOException{ ...
这三者有时往往没有深入的认识,简单地看: Fn:是不可变化的fn; FnMut:是可变的fn; FnOnce:是一次性消费的fn; 但如何理解这些?1、FnOnce:fn consume_with_relish<F&
1、抓包 抓两次2、对比3、我们来方法刨析一下登录 他一定有一个点击事件 我们搜onclick 方法刨析了一下 发现没找到有效的信息4、我们来直接使用jadx-gui来搜索抓取到的字段 居然只发现了一处5、发现字段全部都在这块了6、我们来分析一下这些字段“mzip”我们来看看这个a方法这个a方法 做了一些左移右移等数据操作我们再来看看这个参数aesEncode是Coded.getInstance().aesEncode()方法的返回值aesEncode方法返_陌陌抓包
在基于POSIX标准呢的unix或linux平台上的编程,在大部分取时间的codeblock中一般都会设置时区,但为何TZ用的GMT-8:00,而不是我们一直以为的GMT+08:00,这的确是一个很让人费解的问题,原因其实很简单:因为POSIX的符号规则就是这样的:你只要记住一点就可以了,你想想你要带参数运行某个命令是不是要带个-呢,如ls -lrt。而你在cmd下是不是不用带呢,不用带是不是..._export tz='gmt-08:00