新闻中心

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

【入门教程】EG系列边缘计算网关:Modbus协议转MQTT协议

2024-09-03 09:51:46 阅读: 发布人:纵横智控

需求概述

本章节主要实现一个流程:

1.采集Modbus电表数据上传到MQTT指定topic

2.如果传感器未响应需要发送报警信息到指定topic

3.MQTT连接成功时发送注册信息

4.周期推送心跳到指定topic

5.云端下发控制EG8200继电器并回复


对接资料

1.南向接口 RS485对接协议(标准modbus)


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



2.北向接口协议说明:

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

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

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

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


需求分析

1. 注册与连接工作

a.建立MQTT连接,发布到注册主题(MQTT发布节点)注:MQTT订阅发布节点连接信息共享,其他MQTT无需在配置连接参数,选择第一次配置的连接参数即可

b.监听MQTT连接状态(状态变化节点)

c.封装注册信息(函数节点)


2. 数据上报

a.modbus读取电表数据(modbus读节点)

b.判断传感器是否有回复并封装上报报文(函数节点)

c.配置对应的发布主题(MQTT发布节点)


3. 心跳推送

a.注入节点周期触发(注入节点)

b.封装心跳报文(函数节点)

c.MQTT发布数据(MQTT发布节点)


4. 下发控制

a.MQTT订阅云端下发主题(MQTT订阅节点)

b.解析云端数据,并控制对应DO(函数节点)

c.响应MQTT控制情况(函数节点)

d.上报响应报文(MQTT发布)


实现流程框架

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


需求实现

1. 监听MQTT状态并发布注册信息

a.从节点库拖出一个MQTT发布节点,函数节点,调试节点,状态监测节点和条件判断节点,MQTT发布用于消息发布,函数节点用于注册信息封装,状态检测节点用于检测MQTT的连接状态,调试节点用于打印发布的报文


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



b.从上可以看见日志打印了注册报文,以及MQTTx端以及接收到了注册信息


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


c.注册流程使用的代码块:


const fmt = dateFormat("YYYY-mm-dd HH:MM:SS", new Date())

let obj = {    
    "sn": "82000000305E144F", 
    "time": fmt
    }
function dateFormat(fmt, timestamp) {    
    let ret;    
    const opt = {        
    "Y+": timestamp.getFullYear().toString(), // 年        
    "m+": (timestamp.getMonth() + 1).toString(),  // 月        
    "d+": timestamp.getDate().toString(), // 日        
    "H+": timestamp.getHours().toString(), // 时        
    "M+": timestamp.getMinutes().toString(), // 分        
    "S+": timestamp.getSeconds().toString() // 秒        
    // 有其他格式化字符需求可以继续添加,必须转化成字符串    
    };    
    
    for (let k in opt) {        
    ret = new RegExp("(" + k + ")").exec(fmt);       
    if (ret) {            
    fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))       
     };   
   };    
      return fmt;
}
msg.payload = JSON.stringify(obj)
return msg


2. 数据上报

a.从节点库拖出一个注入节点,函数节点和一个MQTT发布节点,注入节点用于周期触发,函数节点用于封装心跳报文,MQTT发布节点用于心跳发布


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


b.从上面可以看到日志窗口打印了数据报文,MQTTx也接收到了上报数据


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


c.数据上报流程使用的代码块:


function dateFormat(fmt, timestamp) {    
    let ret;    
    const opt = {        
    "Y+": timestamp.getFullYear().toString(), // 年        
    "m+": (timestamp.getMonth() + 1).toString(),  // 月        
    "d+": timestamp.getDate().toString(), // 日        
    "H+": timestamp.getHours().toString(), // 时        
    "M+": timestamp.getMinutes().toString(), // 分        
    "S+": timestamp.getSeconds().toString() // 秒        
    // 有其他格式化字符需求可以继续添加,必须转化成字符串     
    };    
    for (let k in opt) {        
    ret = new RegExp("(" + k + ")").exec(fmt);        
    if (ret) {            
        fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
                };   
           };    
    return fmt;
}
var flag = msg.status
var data = msg.payload
var payloadconst fmt = dateFormat("YYYY-mm-dd HH:MM:SS", new Date())
if (flag == "TIMEOUT") {    
   payload = {        
   "sn": "82000000305E144F",        
   "data": {},        
   "message": "offline",        
   "time": fmt    
   }    
   msg.payload = JSON.stringify(payload)    
   return [msg, null]
}
   
else if (flag == "OK") {    
  payload = {        
  sn: "02C00081275A574E",        
  data,        
  time: fmt   
 
}    
msg.payload = JSON.stringify(payload)    
return [null, msg]}


3. 心跳推送

a.从节点库拿出一个注入节点,函数节点,MQTT发布节点。注入节点用于周期发发送心跳,函数节点用于封装心跳报文,MQTT发布节点用于发布到MQTT


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


b.从上面可以看到日志窗口打印了心跳报文,MQTTx也接收到了心跳报


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


c. 心跳上报流程使用的代码块:


const fmt = dateFormat("YYYY-mm-dd HH:MM:SS", new Date())
function dateFormat(fmt, timestamp) {  
    let ret;  const opt = {    
    "Y+": timestamp.getFullYear().toString(), // 年    
    "m+": (timestamp.getMonth() + 1).toString(),  // 月    
    "d+": timestamp.getDate().toString(), // 日    
    "H+": timestamp.getHours().toString(), // 时    
    "M+": timestamp.getMinutes().toString(), // 分    
    "S+": timestamp.getSeconds().toString() // 秒    /
    / 有其他格式化字符需求可以继续添加,必须转化成字符串  
 };  
 for (let k in opt) {    
     ret = new RegExp("(" + k + ")").exec(fmt);   
     if (ret) {     
          fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))    
         };  
      }; 
     return fmt;
 }
 
let obj = {  
"sn": "82000000305E144F",  
"data": {},  
"message": "heart",  
"time": fmt
}

msg.payload = JSON.stringify(obj)
return msg;


4. 下发控制及响应

a.从节点库拿出一个MQTT订阅节点,MQTT发布节点,函数节点和DO节点,MQTT订阅节点和MQTT发布节点用于接收云端发来的数据和控制响应,函数节点用于解析下发的报文和控制的响应报文封装


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


b.从上面可以看到日志窗口打印了报文,MQTTx也接收到了控制响应


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


c.控制流程使用的代码块


//云端下发解析//
############################

if (msg.payload.length < 10) {
    return 
    }
if (typeof (msg.payload) == "object") {    
var obj = msg.payload    //信息获取    
let event_id = obj.event_id;    
global.set("event_id", event_id)    
let parameter = obj.data.parameter    
let value = obj.data.value    
let arr = []    
switch (parameter) {        
    case "DO1":            
        arr = value           
        break        
    case "DO2":            
        arr = value            
        break   
        
    }
    msg.payload = arr

    return msg;
 }
 
//############################
//反馈响应封装
//############################

let event_id = global.get("event_id")
const fmt = dateFormat("YYYY-mm-dd HH:MM:SS", new Date())function dateFormat(fmt, timestamp) {    
    let ret;    
    const opt = {        
        "Y+": timestamp.getFullYear().toString(), // 年        
        "m+": (timestamp.getMonth() + 1).toString(),  // 月        
        "d+": timestamp.getDate().toString(), // 日        
        "H+": timestamp.getHours().toString(), // 时        
        "M+": timestamp.getMinutes().toString(), // 分        
        "S+": timestamp.getSeconds().toString() // 秒        
        // 有其他格式化字符需求可以继续添加,必须转化成字符串    
        
        };    
    for (let k in opt) {       
        ret = new RegExp("(" + k + ")").exec(fmt);        
        if (ret) {           
            fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))       
          };    
      };    
    return fmt;
}
let obj = {    
"event_id": event_id,    
"message": "OK",    
"data": {},    
"time": fmt
}
msg.payload = JSON.stringify(obj);return msg;

//############################


热门产品