0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

教程-西门子S7协议转换为HTTP协议

IOTRouter 来源:IOTRouter 作者:IOTRouter 2024-10-12 16:18 次阅读

需求概述

本章要实现一个流程:EG8200采集西门子S7-200Smart的数据,并组装成JSON格式通过HTTP上报应用平台。

源-(S7转Modbus-https://www.iotrouter.com/news/2150.html)

要采集的PLC点位表如下:

PLC S7-200 Smart
IP 192.168.0.34/102
点表(DB1)
地址 数据类型 属性 名称
V0.0 Boolean 只读 风机1接触器异常
V0.6 Boolean 只读 风机2接触器异常
V1.6 Boolean 只读 风机3接触器异常
V2.5 Boolean 只读 变频器通讯故障
I0.0 Boolean 只读 电机高温报警
I0.1 Boolean 只读 温度状态异常
VD4 Float 只读 油压工程值
VD8 Float 只读 吸入压力工程值
VD12 Float 只读 燃油油位工程值
VD16 Float 只读 机柜温度值
VD20 Float 只读 发动机电压值
VD24 Float 只读 发动机电流值
VD28 Float 只读 发动机工作时间
VD32 Float 只读 泵压工程值
VW120 Unsigned16 只读 本机编号
VW750 Unsigned16 只读 本机组号
VW2402 Unsigned16 只读 电机1温度
VW2404 Unsigned16 只读 电机2温度
VW2406 Unsigned16 只读 电机3温度
VW2408 Unsigned16 只读 风机1温度
VW2410 Unsigned16 只读 风机2温度
VW2412 Unsigned16 只读 风机3温度

HTTP通信相关参数格式如下:

##数据推送
url:192.168.0.32:1880/api/device/reportData
method:POST

JSON格式:
{
  "deviceInfo": {
    "machineNumber": 9301,
    "machineGroupNumber": 1
  },
  "status": {
    "fan1ContactError": true,
    "fan2ContactError": false,
    "fan3ContactError": false,
    "inverterCommError": false,
    "motorHighTempAlarm": false,
    "temperatureStatusError": false
  },
  "data": {
    "oilPressure": 17.83,
    "suctionPressure": 3.7,
    "fuelLevel": 0.23,
    "cabinetTemperature": 237.2,
    "engineVoltage": 415.64,
    "engineCurrent": 65.1,
    "engineRuntime": 72.6,
    "pumpPressure": 85.3,
    "motor1Temperature": 20,
    "motor2Temperature": 19,
    "motor3Temperature": 19,
    "fan1Temperature": 21,
    "fan2Temperature": 33,
    "fan3Temperature": 26
  },
  "timestamp": "2022-7-08 11:28:55"
}

需求分析

在制作流程时,基础的逻辑是根据数据走向来制作流程。其中主要工作分为三步:

第一步:通过S7协议读取PLC变量数据,得到的数据存储在内存中(西门子节点)

第二步:将数据按照JSON格式进行格式化(函数节点)

第三步:配置HTTP 请求参数

wKgZoWcKMT2AIXGSAAAUBcZlQlY587.png

需求实现

1. 采集PLC数据

从节点库拖入一个西门子节点,以及一个调试节点,调试节点用于查看读取到的PLC数据集,方便定位问

wKgZombDBMSAXaAwAAzV2crvgmE057.png

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

IP:PLC的IP
端口:102(S7协议通信默认端口102)
采集周期:1000ms(默认2000ms,可自定义)
超时周期:2000ms(默认2000ms,可自定义)

数据点配置(根据帮助文档可以找到对应关系)
V0.0
V0.6
V1.6
V2.5
I0.0
I0.1
VD4
VD8
VD12
VD16
VD20
VD24
VD28
VD32
VW120
VW750
VW2402
VW2404
VW2408
VW2410
VW2412

如果是连续地址,可配置起始地址并填写读取长度即可

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

wKgaombDBV6AGjboAAz30bMjHmA001.png

有的时候PLC数据点比较多,手动依次录入比较繁琐。节点支持数据点的导入导出或者参数传递的方式来读取:

wKgZoWcKMZWAemq1ABG6MpMXYKA822.png

本例程用到的传参方案,函数节点内的代码如下:

msg.payload = [
    { func: "ReadBoolArray", body: { name: "", address: "V0", length: 8 } },
    { func: "ReadBoolArray", body: { name: "", address: "V1", length: 8 } },
    { func: "ReadBoolArray", body: { name: "", address: "V2", length: 8 } },
    { func: "ReadFloatArray", body: { name: "", address: "VD4", length: 8 } },
    { func: "ReadUInt16", body: { name: "", address: "VW120" } },
    { func: "ReadUInt16", body: { name: "", address: "VW750" } },
    { func: "ReadUInt16Array", body: { name: "", address: "VW2402", length: 6 } },
    { func: "ReadBoolArray", body: { name: "", address: "I0", length: 8 } }
]
return msg;

2. 数据格式化

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

wKgZoWcKMbSABcQeAAGpKSe5_oI754.png

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

class DeviceReport {
    constructor(machineNumber, machineGroupNumber) {
        this.deviceInfo = {
            machineNumber: machineNumber,
            machineGroupNumber: machineGroupNumber
        };
        this.status = {
            fan1ContactError: 0,
            fan2ContactError: 0,
            fan3ContactError: 0,
            inverterCommError: 0,
            motorHighTempAlarm: 0,
            temperatureStatusError: 0
        };
        this.data = {
            oilPressure: 0,
            suctionPressure: 0,
            fuelLevel: 0,
            cabinetTemperature: 0,
            engineVoltage: 0,
            engineCurrent: 0,
            engineRuntime: 0,
            pumpPressure: 0,
            motor1Temperature: 0,
            motor2Temperature: 0,
            motor3Temperature: 0,
            fan1Temperature: 0,
            fan2Temperature: 0,
            fan3Temperature: 0
        };
        this.timestamp = null;
    }

    // 设置状态数据(1表示异常,0表示正常)
    setStatusData(statusData) {
        this.status = statusData;
    }

    // 设置传感器数据
    setSensorData(sensorData) {
        this.data = sensorData;
    }

    // 设置时间戳
    setTimestamp(timestamp) {
        this.timestamp = timestamp;
    }
    generateReport() {
        return {
            deviceInfo: this.deviceInfo,
            status: this.status,
            data: this.data,
            timestamp: this.timestamp
        };
    }
}

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;
}
function setValue(data) {
    var myDeviceReport = new DeviceReport(data.VW120, data.VW750)
    var v0 = data.V0
    var v1 = data.V1
    var v2 = data.V2
    var i0 = data.I0
    var vd4 = data.VD4
    var vd2402 = data.VW2402
    const fmt = dateFormat("YYYY-mm-dd HH:MM:SS", new Date())
    try {
        // 设置状态数据
        const statusData = {
            fan1ContactError: v0[0],
            fan2ContactError: v0[6],
            fan3ContactError: v1[6],
            inverterCommError: v2[5],
            motorHighTempAlarm: i0[0],
            temperatureStatusError: i0[1]
        }
        myDeviceReport.setStatusData(statusData)

        // 设置传感器数据
        const sensorData = {
            oilPressure: vd4[0],
            suctionPressure: vd4[1],
            fuelLevel: vd4[2],
            cabinetTemperature: vd4[3],
            engineVoltage: vd4[4],
            engineCurrent: vd4[5],
            engineRuntime: vd4[6],
            pumpPressure: vd4[7],
            motor1Temperature: vd2402[0],
            motor2Temperature: vd2402[1],
            motor3Temperature: vd2402[2],
            fan1Temperature: vd2402[3],
            fan2Temperature: vd2402[4],
            fan3Temperature: vd2402[5]
        }
        myDeviceReport.setSensorData(sensorData)
        // 设置时间戳
        myDeviceReport.setTimestamp(fmt)
        //生成JSON对象返回
        return myDeviceReport.generateReport()
    } catch (err) {
        node.error(err.message);
        return null
    }

}
var plcData = msg.payload
if (setValue(plcData)){
    msg.payload = JSON.stringify(setValue(plcData),null,2)
    return msg
}

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

wKgaoWcKMciAHmhAABAECOnz8Go273.png

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

3. 通过http周期上报

拖入一个HTTP节点,根据提示进行配置地址和请求方式,即可实现数据上报:

wKgaoWcKMdOAaHycAA5n4n7XdF0777.png

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

源码

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

[{"id":"edf0c4c538469caa","type":"Siemens","z":"5bb1b94e3403e2f2","name":"","protocol":"iplink_SiemensS7","IPAddress":"192.168.0.34","DestPort":"102","IPLinkTimeout":"2000","IPCommTimeout":"2000","Spname":"COM10","Baudrate":"9600","Databits":"8","Stopbit":"1","Paritybit":"0","RTSEnable":false,"SpLinktimeout":"2000","SpIntertimeout":"-1","workMode":"read","readMode":"trigger","readCyc":"1000","vartable":[],"SiemensS7Model":"5","SiemensS7ConnectionType":"1","SiemensS7Rack":"0","SiemensS7Slot":"0","SiemensS7LocalTSAP":"102","SiemensS7DestTSAP":"4D57","SiemensPPIStation":"2","stringvar":[],"customName":"Siemens:S7-S200Smart","x":510,"y":1080,"wires":[["be890e0383a04306"]]},{"id":"90be80aa485c48ae","type":"debug","z":"5bb1b94e3403e2f2","name":"调试 22","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1020,"y":1080,"wires":[]},{"id":"2485d94e74e61614","type":"function","z":"5bb1b94e3403e2f2","name":"函数计算 18","func":"msg.payload = [n    { func: "ReadBoolArray", body: { name: "", address: "V0", length: 8 } },n    { func: "ReadBoolArray", body: { name: "", address: "V1", length: 8 } },n    { func: "ReadBoolArray", body: { name: "", address: "V2", length: 8 } },n    { func: "ReadFloatArray", body: { name: "", address: "VD4", length: 8 } },n    { func: "ReadUInt16", body: { name: "", address: "VW120" } },n    { func: "ReadUInt16", body: { name: "", address: "VW750" } },n    { func: "ReadUInt16Array", body: { name: "", address: "VW2402", length: 6 } },n    { func: "ReadBoolArray", body: { name: "", address: "I0", length: 8 } }n]nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":1080,"wires":[["edf0c4c538469caa"]]},{"id":"8db3c718ecac3ed7","type":"inject","z":"5bb1b94e3403e2f2","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":1080,"wires":[["2485d94e74e61614"]]},{"id":"be890e0383a04306","type":"function","z":"5bb1b94e3403e2f2","name":"函数计算 19","func":"class DeviceReport {n    constructor(machineNumber, machineGroupNumber) {n        this.deviceInfo = {n            machineNumber: machineNumber,n            machineGroupNumber: machineGroupNumbern        };n        this.status = {n            fan1ContactError: 0,n            fan2ContactError: 0,n            fan3ContactError: 0,n            inverterCommError: 0,n            motorHighTempAlarm: 0,n            temperatureStatusError: 0n        };n        this.data = {n            oilPressure: 0,n            suctionPressure: 0,n            fuelLevel: 0,n            cabinetTemperature: 0,n            engineVoltage: 0,n            engineCurrent: 0,n            engineRuntime: 0,n            pumpPressure: 0,n            motor1Temperature: 0,n            motor2Temperature: 0,n            motor3Temperature: 0,n            fan1Temperature: 0,n            fan2Temperature: 0,n            fan3Temperature: 0n        };n        this.timestamp = null;n    }nn    // 设置状态数据(1表示异常,0表示正常)n    setStatusData(statusData) {n        this.status = statusData;n    }nn    // 设置传感器数据n    setSensorData(sensorData) {n        this.data = sensorData;n    }nn    // 设置时间戳n    setTimestamp(timestamp) {n        this.timestamp = timestamp;n    }n    generateReport() {n        return {n            deviceInfo: this.deviceInfo,n            status: this.status,n            data: this.data,n            timestamp: this.timestampn        };n    }n}nnfunction dateFormat(fmt, timestamp) {n    let ret;n    const opt = {n        "Y+": timestamp.getFullYear().toString(), // 年n        "m+": (timestamp.getMonth() + 1).toString(),  // 月n        "d+": timestamp.getDate().toString(), // 日n        "H+": timestamp.getHours().toString(), // 时n        "M+": timestamp.getMinutes().toString(), // 分n        "S+": timestamp.getSeconds().toString() // 秒n    };n    for (let k in opt) {n        ret = new RegExp("(" + k + ")").exec(fmt);n        if (ret) {n            fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))n        };n    };n    return fmt;n}nfunction setValue(data) {n    var myDeviceReport = new DeviceReport(data.VW120, data.VW750)n    var v0 = data.V0n    var v1 = data.V1n    var v2 = data.V2n    var i0 = data.I0n    var vd4 = data.VD4n    var vd2402 = data.VW2402n    const fmt = dateFormat("YYYY-mm-dd HH:MM:SS", new Date())n    try {n        // 设置状态数据n        const statusData = {n            fan1ContactError: v0[0],n            fan2ContactError: v0[6],n            fan3ContactError: v1[6],n            inverterCommError: v2[5],n            motorHighTempAlarm: i0[0],n            temperatureStatusError: i0[1]n        }n        myDeviceReport.setStatusData(statusData)nn        // 设置传感器数据n        const sensorData = {n            oilPressure: vd4[0],n            suctionPressure: vd4[1],n            fuelLevel: vd4[2],n            cabinetTemperature: vd4[3],n            engineVoltage: vd4[4],n            engineCurrent: vd4[5],n            engineRuntime: vd4[6],n            pumpPressure: vd4[7],n            motor1Temperature: vd2402[0],n            motor2Temperature: vd2402[1],n            motor3Temperature: vd2402[2],n            fan1Temperature: vd2402[3],n            fan2Temperature: vd2402[4],n            fan3Temperature: vd2402[5]n        }n        myDeviceReport.setSensorData(sensorData)n        // 设置时间戳n        myDeviceReport.setTimestamp(fmt)n        //生成JSON对象返回n        return myDeviceReport.generateReport()n    } catch (err) {n        node.error(err.message);n        return nulln    }nn}nvar plcData = msg.payloadnif (setValue(plcData)) {n    msg.payload = JSON.stringify(setValue(plcData), null, 2)n    return msgn}n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":1080,"wires":[["d140dc012c0cd68f"]]},{"id":"d140dc012c0cd68f","type":"http request","z":"5bb1b94e3403e2f2","name":"","method":"POST","ret":"txt","paytoqs":"ignore","url":"192.168.0.32:1880/api/device/reportData","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":860,"y":1080,"wires":[["90be80aa485c48ae"]]}]


审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 西门子
    +关注

    关注

    94

    文章

    3038

    浏览量

    115844
  • HTTP
    +关注

    关注

    0

    文章

    505

    浏览量

    31213
  • 边缘计算
    +关注

    关注

    22

    文章

    3089

    浏览量

    48942
收藏 人收藏

    评论

    相关推荐

    西门子PLC S7-1500系列介绍

    西门子PLCS7-1500系列是西门子自动化领域中的一款重要产品,它以其卓越的性能、强大的功能和高度的灵活性,在工业自动化控制系统中占据了一席之地。本文将详细介绍西门子PLC
    的头像 发表于 12-09 18:23 304次阅读
    <b class='flag-5'>西门子</b>PLC <b class='flag-5'>S7</b>-1500系列介绍

    西门子S7协议PLC数据采集到MQTT物联网平台  

    ,广泛应用于各种工业控制场合。而MQTT(消息队列遥测传输)物联网平台则以其高效的消息传输机制和数据处理能力,为物联网设备提供了强大的连接、管理和数据处理服务。 对此,物通博联提供基于工业智能网关实现西门子S7协议PLC数据采集
    的头像 发表于 09-26 10:42 306次阅读
    <b class='flag-5'>西门子</b><b class='flag-5'>S7</b><b class='flag-5'>协议</b>PLC数据采集到MQTT物联网平台   

    EG网关采集西门子S7-200smart转Modbus协议

    通过EG边缘计算网关,用户可以轻松实现西门子S7-200 Smart PLC数据的采集,并将其转换为标准Modbus协议输出。这种跨协议的数
    的头像 发表于 09-10 10:42 519次阅读
    EG网关采集<b class='flag-5'>西门子</b><b class='flag-5'>S7</b>-200smart转Modbus<b class='flag-5'>协议</b>

    西门子 S7 通信协议大揭秘

    什么是S7协议 有网友说,如果 S7 是一辆汽车,它可能看起来像这样: 实际上,西门子S7协议
    的头像 发表于 08-12 14:21 739次阅读
    <b class='flag-5'>西门子</b> <b class='flag-5'>S7</b> 通信<b class='flag-5'>协议</b>大揭秘

    基于多协议转换工业物联网网关采集西门子PLC设备数据

    作为全球领先的自动化解决方案提供商,西门子的PLC设备以其稳定性和高效性广受赞誉。然而,在实际应用过程中,由于其采用的是专有的通信协议,与其他设备之间的互联互通成为了一大难题。这就需要一个多协议
    的头像 发表于 08-12 13:41 225次阅读

    西门子总线协议有哪些

    西门子(Siemens)作为工业自动化领域的领先企业,其总线协议在自动化系统中发挥着重要作用。西门子总线协议主要包括了多种类型,这些协议支持
    的头像 发表于 08-05 16:09 1040次阅读

    S7协议读取西门子S7-200 Smart PLC数据

    西门子S7-200 Smart PLC因其稳定性和易用性而广泛应用。通过使用S7协议,可以实现对PLC数据的高效读取和控制。本文将详细介绍如何使用S
    的头像 发表于 07-11 11:55 5749次阅读
    <b class='flag-5'>S7</b><b class='flag-5'>协议</b>读取<b class='flag-5'>西门子</b><b class='flag-5'>S7</b>-200 Smart PLC数据

    宏集物联网工控屏通过 S7 ETH 协议采集西门子 1200 PLC 数据

    上周我们分享了宏集HMI通过S7 MPI协议采集西门子400 PLC数据的操作步骤。本周,我们将继续带来干货,重点介绍宏集HMI如何通过S7 ETH
    的头像 发表于 06-21 16:02 526次阅读
    宏集物联网工控屏通过 <b class='flag-5'>S7</b> ETH <b class='flag-5'>协议</b>采集<b class='flag-5'>西门子</b> 1200 PLC 数据

    西门子S7协议与TCP协议的区别

    在工业自动化领域,通信协议的选择对于确保设备间的顺畅通信和数据的可靠传输至关重要。西门子S7协议和TCP协议作为两种常用的通信
    的头像 发表于 06-19 15:54 3618次阅读

    干货分享:宏集物联网HMI通过S7 MPI协议采集西门子400PLC数据

    宏集物联网HMI集成了多个驱动来适配西门子200、300、400、1200、1500、LOGO等系列PLC,本文主要介绍宏集HMI通过S7 MPI协议采集西门子400PLC数据的操作步
    的头像 发表于 06-13 13:39 583次阅读
    干货分享:宏集物联网HMI通过<b class='flag-5'>S7</b> MPI<b class='flag-5'>协议</b>采集<b class='flag-5'>西门子</b>400PLC数据

    西门子plc模块型号详解

    的模块型号,以帮助您更好地了解和选择适合自己需求的PLC模块。 西门子S7系列PLC模块 西门子S7系列PLC是其最经典的PLC产品系列,包括S7
    的头像 发表于 06-11 16:18 5966次阅读

    非夕科技与西门子达成战略合作协议,正式加入西门子Xcelerator生态

    近日,Flexiv非夕科技与西门子达成战略合作协议,正式加入西门子 Xcelerator 生态,双方将联合打造面向多行业的自适应机器人应用解决方案。
    的头像 发表于 05-24 14:49 782次阅读

    西门子网口S7-COMM协议300 400如何使用?

    。网关使用 西门子****300/400 协议驱动 , 按照下述过程操作即可实现与PLC直接通讯(协议名称为S7-COMM)。 本文以 西门子
    的头像 发表于 04-18 16:18 947次阅读
    <b class='flag-5'>西门子</b>网口<b class='flag-5'>S7</b>-COMM<b class='flag-5'>协议</b>300  400如何使用?

    组态软件与西门子S7系列PLC及三菱PLC间的无线通信测试

    组态软件与西门子S7系列PLC及三菱PLC间的无线通信测试需要用到以下设备: l 西门子PLC型号:S7-200Smart × 2台 l 三菱PLC型号:FX5U × 2台 l 上位机
    的头像 发表于 03-13 14:54 466次阅读
    组态软件与<b class='flag-5'>西门子</b><b class='flag-5'>S7</b>系列PLC及三菱PLC间的无线通信测试

    杭氧与西门子签署合作协议

    杭氧与西门子签署合作协议 3月7日杭州制氧机集团有限公司与西门子签署战略合作协议;杭氧与西门子
    的头像 发表于 03-11 11:58 576次阅读