新闻中心

PRESS CENTER 纵横智控
你的位置: 首页 新闻 技术应用
纵横智控

【快速入门教程】通过EG系列边缘网关编程界面创建第二个流程

2023-12-13 17:40:35 阅读: 发布人:纵横智控

需求概述

本章节主要实现一个流程:EG8200采集西门子S7-200 Smart的数据,并组装成JSON格式,通过MQTT上报应用平台;同时能够接收应用平台下发的控制命令,实现远程开关。要实现此流程,需要提前准备好以下材料:

  1. 要采集的PLC的IP端口以及点位表,例如:

PLC

S7-200 Smart

IP

192.168.0.24/102

点表(DB1)

地址

数据类型

属性

名称

V0.0

Boolean

只读

1号电机启停状态

V0.1

Boolean

只读

2号电机启停状态

V0.2

Boolean

只读

3号电机启停状态

V0.3

Boolean

只读

4号电机启停状态

V0.4

Boolean

读写

1号电机启停控制

V0.5

Boolean

读写

2号电机启停控制

V0.6

Boolean

读写

3号电机启停控制

V0.7

Boolean

读写

4号电机启停控制

VD100

Unsigned16

只读

电压(V)

VD200

Unsigned16

只读

电流(A)

  1. MQTT通信相关参数及JSON数据格式要求,例如:

url:1883.dtuip.com:1883
clientID:820000003058164F
username:19381903226
password:ZHZK19381903226
订阅:820000003058164F/+
发布:820000003058164F

JSON格式:
{
	"sensorDatas":
	[
		{
			"flag":"em1Status",
			"switcher":1
		},
		{
			"flag":"em2Status",
			"switcher":1
		},
		{
			"flag":"em3Status",
			"switcher":1
		},
		{
			"flag":"em4Status",
			"switcher":1
		},
		{
			"flag":"em1Control",
			"switcher":0
		},
		{
			"flag":"em2Control",
			"switcher":0
		},
		{
			"flag":"em3Control",
			"switcher":0
		},
		{
			"flag":"em4Control",
			"switcher":0
		},
		{
			"flag":"voltage",
			"value":220.0
		},
		{
			"flag":"current",
			"value":10.2
		}
	]
}

需求分析

在制作流程时,基础的逻辑是根据数据走向来制作流程该需求经过分析可以得出,主要分为数据上行和数据下行两个部分。其中,数据上行主要工作有:

    1. 通过S7协议读取PLC的数据,得到的数据存储在内存中(S7节点

    2. 将数据按照JSON格式进行格式化(函数节点

    3. 建立MQTT连接,发布到指定主题(MQTT发布节点

数据下行主要工作有:

    1. 订阅MQTT主题,接收平台下发数据(MQTT订阅节点

    2. 将收到的JSON数据解析后存储在内存中(函数节点

    3. 按照S7要求的格式写入PLC中(S7节点

需求分析

需求实现

1. 采集PLC数据

    1. 从节点库拖入一个S7读数据节点,以及一个调试节点调试节点用于查看读取到的PLC的数据,方便定位问题

采集PLC数据

    1. 双击S7读数据节点,根据需求概述的内容填写对应的设置参数,如下图所示:

IP:PLC的IP
端口:102(S7协议通信默认端口102)
模式:TASP(S7-200 Smart选择TASP,其余型号选择Rack/Slot)
本地TSAP:1002(固定值)
远端TSAP:0301(固定值)
采集周期:1000ms(默认1000ms,可自定义)
超时周期:2000ms(默认2000ms,可自定义)

数据点配置(根据帮助文档可以找到对应关系)
V0.0-->DB1,X0.0
V0.1-->DB1,X0.1
V0.2-->DB1,X0.2
V0.3-->DB1,X0.3
V0.4-->DB1,X0.4
V0.5-->DB1,X0.5
V0.6-->DB1,X0.6
V0.7-->DB1,X0.7
VD100 -->DB1,W100
VD200 -->DB1,W200

输出模式可以根据需求选择,这里选择所有变量输出一条

如果设置正确,调试窗口会有日志打印,显示的是读取到的数据内容

读取数据内容

    1. 有的时候PLC数据点比较多,手动依次录入比较繁琐。节点支持数据点的导入导出:

节点导入导出


2. 数据格式化

根据步骤2的引导,在调试窗口可以看到读到的PLC数据如下:

数据格式化

因为应用平台已经规定了数据必须按照JSON格式上报。接下来使用函数节点Javascrip代码将数据进行格式化,代码如下:

let jsonArray = []

jsonArray.push({ "flag": "em1Status", "switcher": msg.payload.em1Status == true ? 1 : 0 })
jsonArray.push({ "flag": "em2Status", "switcher": msg.payload.em2Status == true ? 1 : 0 })
jsonArray.push({ "flag": "em3Status", "switcher": msg.payload.em3Status == true ? 1 : 0 })
jsonArray.push({ "flag": "em4Status", "switcher": msg.payload.em4Status == true ? 1 : 0 })
jsonArray.push({ "flag": "em1Control", "switcher": msg.payload.em1Control == true ? 1 : 0 })
jsonArray.push({ "flag": "em2Control", "switcher": msg.payload.em2Control == true ? 1 : 0 })
jsonArray.push({ "flag": "em3Control", "switcher": msg.payload.em3Control == true ? 1 : 0 })
jsonArray.push({ "flag": "em4Control", "switcher": msg.payload.em4Control == true ? 1 : 0 })
jsonArray.push({ "flag": "voltage", "value": msg.payload.voltage / 100 })/*两位小数*/
jsonArray.push({ "flag": "current", "value": msg.payload.current / 100 })/*两位小数*/

let data = {}
data.sensorDatas = jsonArray

msg.payload = JSON.stringify(data)

return msg

复制以上代码,粘贴到函数节点内,部署后即可看到效果:

数据格式化

可以看到,已经将读到的PLC数据,按照需求要求转换成了最终的JSON格式,且对数据进行了一定程度的计算(两位小数)。此处只是函数节点的冰山一角,因为支持Javascrip语言编程,几乎你能想到的任何功能都可以在这里实现

读取数据内容

3. 通过MQTT上报数据

拖入一个MQTT发布节点,根据提示进行配置,填入MQTT连接相关信息及MQTT发布主题后(详情见需求概述),即可实现数据上报。可以看到,数据上报成功后,应用平台显示绿色表明设备上线且数据正常:

通过MQTT上报数据

至此,数据上报已经完成,很简单几步即可实现:采集PLC数据并按照自定义JSON格式上报。

4. 通过MQTT接收数据

拖入一个MQTT订阅节点,注意:MQTT发布节点MQTT订阅节点可以共用一个MQTT连接,如果使用的是同一个连接,只是不同的Topic,拖入节点后选择已经配置好的连接即可。如果选择添加新的mqtt-broker节点,则代表的是新建一个MQTT连接

通过MQTT接收数据

选择一个调试节点,在平台点击控制按钮后,调试窗口可以看到下发的指令:

调试节点

5. 数据解析

根据S7写数据节点的帮助文档,可以知道,要想实现向PLC写入数据,需要传递的数据携带两个参数,如下:

数据解析

因此,数据解析时,需要将应用平台下发的数据转换为携带payloadvariable两个变量的消息,传递给S7写数据节点,函数节点的代码如下:

let cmdDate = msg.payload

msg.variable = cmdDate.sensorDatas[0].flag
msg.payload = cmdDate.sensorDatas[0].switcher == 1 ? true : false

return msg

复制以上代码,粘贴到函数节点内,将调试节点设置为输出原始消息,可以看到打印内容如下:

边缘计算网关/物联网平台/网关模块/纵横智控

可以看到数据已经转换为S7写数据节点要求的格式

S7写数据节点

6. 写入PLC

拖入一个S7写数据节点,连接函数计算节点,在应用平台操作开关,看演示效果:

写入PLC

总结

本章节介绍了一个相对复杂的流程,旨在表述网关所具备的能力,因此并未对程序的安全性、稳定性、灵活性等方面做优化。通过理解本流程,相信你已经对网关的可视化编程有了一定的熟悉。接下来,深入学习每个节点的功能用法吧,掌握它们将会为你制作更复杂的流程提供更多的选择和可能!

源码

所有的流程支持以json格式导入导出,方便与其他人分享做好的流程。本章节的流程json文件如下,复制后在菜单栏右上角选择导入粘贴即可,导出同理

[{"id":"c8d138cd30e452fc","type":"s7 in","z":"2ff624305b8cb30b","endpoint":"374f5d9e3d2741c0","mode":"all","variable":"","diff":false,"name":"读PLC数据","x":180,"y":180,"wires":[["03f0b9014af25c1d"]]},{"id":"4abb25e7e75b3447","type":"mqtt out","z":"2ff624305b8cb30b","name":"发布数据","topic":"820000003058164F","qos":"0","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"8d85be060cbc6545","x":520,"y":180,"wires":[]},{"id":"63f2816a781192d5","type":"mqtt in","z":"2ff624305b8cb30b","name":"订阅数据","topic":"820000003058164F/+","qos":"0","datatype":"auto-detect","broker":"8d85be060cbc6545","nl":false,"rap":true,"rh":0,"inputs":0,"x":180,"y":260,"wires":[["1b6776e208355720"]]},{"id":"03f0b9014af25c1d","type":"function","z":"2ff624305b8cb30b","name":"数据格式化","func":"let jsonArray = []

jsonArray.push({ "flag": "em1Status", "switcher": msg.payload.em1Status == true ? 1 : 0 })
jsonArray.push({ "flag": "em2Status", "switcher": msg.payload.em2Status == true ? 1 : 0 })
jsonArray.push({ "flag": "em3Status", "switcher": msg.payload.em3Status == true ? 1 : 0 })
jsonArray.push({ "flag": "em4Status", "switcher": msg.payload.em4Status == true ? 1 : 0 })
jsonArray.push({ "flag": "em1Control", "switcher": msg.payload.em1Control == true ? 1 : 0 })
jsonArray.push({ "flag": "em2Control", "switcher": msg.payload.em2Control == true ? 1 : 0 })
jsonArray.push({ "flag": "em3Control", "switcher": msg.payload.em3Control == true ? 1 : 0 })
jsonArray.push({ "flag": "em4Control", "switcher": msg.payload.em4Control == true ? 1 : 0 })
jsonArray.push({ "flag": "voltage", "value": msg.payload.voltage / 100 })/*两位小数*/
jsonArray.push({ "flag": "current", "value": msg.payload.current / 100 })/*两位小数*/

let data = {}
data.sensorDatas = jsonArray

msg.payload = JSON.stringify(data)

return msg
","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":180,"wires":[["4abb25e7e75b3447"]]},{"id":"1b6776e208355720","type":"function","z":"2ff624305b8cb30b","name":"函数计算 1","func":"let cmdDate = msg.payload

msg.variable = cmdDate.sensorDatas[0].flag
msg.payload = cmdDate.sensorDatas[0].switcher == 1 ? true : false

return msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":260,"wires":[["140b525dd4d0608b"]]},{"id":"140b525dd4d0608b","type":"s7 out","z":"2ff624305b8cb30b","endpoint":"374f5d9e3d2741c0","variable":"","name":"","x":510,"y":260,"wires":[]},{"id":"374f5d9e3d2741c0","type":"s7 endpoint","transport":"iso-on-tcp","address":"192.168.0.24","port":"102","rack":"0","slot":"2","localtsaphi":"10","localtsaplo":"02","remotetsaphi":"03","remotetsaplo":"01","connmode":"tsap","adapter":"","busaddr":"2","cycletime":"2000","timeout":"2000","name":"PLC","vartable":[{"addr":"DB1,X0.0","name":"em1Status"},{"addr":"DB1,X0.1","name":"em2Status"},{"addr":"DB1,X0.2","name":"em3Status"},{"addr":"DB1,X0.3","name":"em4Status"},{"addr":"DB1,X0.4","name":"em1Control"},{"addr":"DB1,X0.5","name":"em2Control"},{"addr":"DB1,X0.6","name":"em3Control"},{"addr":"DB1,X0.7","name":"em4Control"},{"addr":"DB1,W100","name":"voltage"},{"addr":"DB1,DW200","name":"current"}]},{"id":"8d85be060cbc6545","type":"mqtt-broker","name":"","broker":"1883.dtuip.com:1883","port":"1883","clientid":"820000003058164F","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]

注意

MQTT配置节点导出时,不会携带用户名和密码。因此导入时需要重新录入用户名和密码


热门产品