文档｜EdgeX 设备微服务之西门子 S7 -- device-s7 完整使用手册
EdgeX Foundry （以下统一简称：EdgeX）设备微服务 device-s7 由我司贡献给社区，文档也是必不可少的环节，社区要求英文，现翻译成中文，方便国内客户阅读和使用。 目录 目的 入门 环境 设置 S7 设备 设置 ISO-on-TCP 访问 IP protocol 启用 S7 Communication 远程访问 (可选) 保留 S7 communication 设置数据块 Data Blocks 启动微服务之前 使用预定义的配置进行测试 预定义 Device Profile 预定义设备配置 Device Configuration 设置一个新的配置 Configuration 创建自定义配置文件夹 设置新的设备配置 Device Profile 设置设备服务配置 Configuration 准备 docker-compose 文件 生成 docker compose 文件 将自定义配置添加到 docker-compose 文件 在 Docker 上启动 EdgeX Foundry 启动服务后设置 执行命令 查找可执行命令 执行设置命令 执行获取命令 自动事件 配置 协议属性 API 参考 源代码 额外细节 读命令 Read Command 写命令 Write Command 何时转换数据 支持的转换 "亿琪软件" "联系我们--商业服务" 目的 该服务的目的是将西门子 S7 PLC 设备连接到 EdgeX。 入门 本页介绍如何将 S7 设备连接到 EdgeX。 在此示例中，我们使用真实设备（例如 S7-1200）。 这提供了一种测试设备服务功能的简单方法。 环境 您可以使用任何可以安装 docker 和 docker-compose 的操作系统。 在本例中，我们使用 Ubuntu 使用 docker 部署 EdgeX。 设置 S7 设备 !!! warning "警告" 本页面并不是设置 S7 设备的完整指南，仅介绍了几个重要步骤。 设置 ISO-on-TCP 访问 IP protocol 设置 Ethernet addresses -> IP protocol, 例如： 192.168.123.199/255.255.255.0 启用 S7 Communication 远程访问 启用 Permit access with PUT/GET communication from remote partner. (可选) 保留 S7 communication S7 Communication 保留和使用的资源数量，“Configured” 为 0，表示 EdgeX 最多可以建立 8 个连接。 !!! warning "提示" 重要提示：不要与单个 S7 设备创建超过“6”个连接！ 我们需要为 WINCC 保留 “2” 个连接。 设置数据块 Data Blocks Data Block 1 在本例子中，只需使用 Clcok 偏移量 160.0 中的进行测试即可。 Data Block 4 在本例子中, 使用 bool, byte, word, dword, int, dint, real 作为测试. 启动微服务之前 以下部分介绍如何在启动服务之前完成设置。 使用预定义的配置进行测试 设置新配置 使用预定义的配置进行测试 文件夹中的预定义配置：cmd/res/ 预定义 Device Profile 设备配置 Device Profile profiles/Simple-Driver.yaml 描述了一个 S7-1200 设备，它包含 8 个资源，如下所示： name: S7-Device manufacturer: YIQISOFT description: Example of S7 Device model: Siemens S7 labels: [ISO-on-TCP] deviceResources: - name: bool description: PLC bool isHidden: false properties: valueType: Bool readWrite: RW attributes: NodeName: DB4.DBX0.0 - name: byte description: PLC byte isHidden: false properties: valueType: Uint8 readWrite: RW attributes: NodeName: DB4.DBB1 - name: word description: PLC word isHidden: false properties: valueType: Int16 readWrite: RW attributes: NodeName: DB4.DBW2 - name: dword description: PLC dword isHidden: false properties: valueType: Int32 readWrite: RW attributes: NodeName: DB4.DBD4 - name: int description: PLC int isHidden: false properties: valueType: Int16 readWrite: RW attributes: NodeName: DB4.DBW8 - name: dint description: PLC dint isHidden: false properties: valueType: Int32 readWrite: RW attributes: NodeName: DB4.DBW10 - name: real description: PLC real isHidden: false properties: valueType: Float32 readWrite: RW attributes: NodeName: DB4.DBD14 - name: heartbeat description: PLC heartbeat isHidden: false properties: valueType: Int16 readWrite: RW attributes: NodeName: DB1.DBW160 deviceCommands: - name: AllResource isHidden: false readWrite: RW resourceOperations: - deviceResource: bool defaultValue: 'false' - deviceResource: byte defaultValue: '0' - deviceResource: word defaultValue: '0' - deviceResource: dword defaultValue: '0' - deviceResource: int defaultValue: '0' - deviceResource: dint defaultValue: '0' - deviceResource: real defaultValue: '0' - deviceResource: heartbeat defaultValue: '0' 该表描述了设备配置文件的每个资源： Resource Name valueType of EdgeX NodeName Note(DB: Data Block) bool Bool DB4.DBX0.0 DB4: DBX0.0: (BOOL) bit 0 of offset 0 byte Uint8 DB4.DBB1 DB4, DBB1: (BYTE) one byte of offset 1 word Int16 DB4.DBW2 DB4, DBW2: (WORD) two bytes of offset 2 dword Int32 DB4.DBD4 DB4, DBD4: (DWORD) four bytes of offset 4 int Int16 DB4.DBW8 DB4, DBW8: (WORD) two bytes of offset 8 dint Int32 DB4.DBW10 DB4, DBW10: (WORD) two bytes of offset 10 real Float32 DB4.DBD14 DB4, DBD14: (REAL) four bytes of offset 14 heartbeat Int16 DB1.DBW160 DB1, DBW160: (WORD) two bytes of offset 160 预定义设备配置 Device Configuration 设备配置 Device Configuration devices/Simple-Device.yaml 描述了如下所示的两种设备。 S7-Device01：自动事件“interval”值(10s) < IdleTimeout(30s)，只有一个 tcp 连接，直到连接失败。 S7-Device02：自动事件“interval”值（10s）> IdleTimeout（5s），因此每个读/写命令都会重新连接到 S7 设备。 deviceList: - name: S7-Device01 profileName: S7-Device description: Example of S7 Device labels: [industrial] protocols: s7: Host: 192.168.123.199 Port: 102 Rack: 0 Slot: 1 Timeout: 30 IdleTimeout: 30 autoEvents: - interval: 10s onChange: false sourceName: AllResource - name: S7-Device02 profileName: S7-Device description: Example of S7 Device labels: [industrial] protocols: s7: Host: 192.168.123.199 Port: 102 Rack: 0 Slot: 1 Timeout: 5 IdleTimeout: 5 autoEvents: - interval: 10s onChange: false sourceName: heartbeat 设置一个新的配置 Configuration 创建自定义配置文件夹 运行以下命令： mkdir -p custom-config 设置新的设备配置 Device Profile 运行以下命令来创建您的设备配置文件： cd custom-config vi new-device-profile.yaml 插入您的设备配置文件定义，这取决于您的 S7 设备配置。 设置设备服务配置 Configuration cd custom-config vi new-device-config.yaml 填写 new-device-config.yaml 文件。 准备 docker-compose 文件 生成 docker compose 文件 Clone edgex-compose git clone https://github.com/edgexfoundry/edgex-compose.git 生成 docker-compose.yml 文件 cd edgex-compose make gen ds-s7 将自定义配置添加到 docker-compose 文件 将准备好的配置文件添加到 docker-compose 文件中，您可以使用卷挂载它们并更改 device-s7 内部使用的环境。 打开 docker-compose.yml 文件，然后添加卷路径和环境，如下所示： device-s7: ... environment: ... DEVICE_PROFILESDIR: /custom-config DEVICE_DEVICESDIR: /custom-config volumes: ... - /path/to/custom-config:/custom-config 在 Docker 上启动 EdgeX Foundry 由于我们在上一步中生成了 docker-compose.yml 文件，因此我们可以部署 EdgeX，如下所示： cd edgex-compose/compose-builder docker compose -p edgex up -d [+] Running 12/12 ✔ Container edgex-core-consul Started 0.0s ✔ Container edgex-ui-go Started 0.0s ✔ Container edgex-redis Started 0.0s ✔ Container edgex-core-common-config-bootstrapper Started 0.1s ✔ Container edgex-support-scheduler Started 0.0s ✔ Container edgex-kuiper Started 0.0s ✔ Container edgex-support-notifications Started 0.1s ✔ Container edgex-core-metadata Started 0.1s ✔ Container edgex-core-command Started 0.0s ✔ Container edgex-core-data Started 0.0s ✔ Container edgex-app-rules-engine Started 0.0s ✔ Container edgex-device-s7 Started 0.0s 启动服务后设置 如果服务已在运行并且您想要添加设备，则可以使用本节中概述的“核心元数据 API”。 如果您按照启动服务之前的设置中的说明设置设备配置文件和服务，则可以跳过此部分。 要在启动服务后添加设备，请完成以下步骤： 使用 POST 将上面的设备配置文件上传到元数据：http://localhost:59881/api/v3/deviceprofile/uploadfile ，并以表单数据格式将文件作为密钥“文件”添加到正文，以及创建的 ID 将被退回。 以下示例命令使用 curl 发送请求： curl http://localhost:59881/api/v3/deviceprofile/uploadfile -F "file=@new-device-profile.yml" 确保 S7 设备服务正在运行，如有必要或使用其他设备服务，请调整下面的服务名称以匹配。 使用 POST 将设备添加到 http://localhost:59881/api/v3/device，正文将类似于： curl http://localhost:59881/api/v3/device -H "Content-Type:application/json" -X POST \ -d '[ { "apiVersion" : "v3", "device": { "name": "S7-Device03", "description": "Example of S7 Device", "adminState": "UNLOCKED", "operatingState": "UP", "serviceName": "device-s7", "profileName": "S7-Device", "protocols": { "s7": { "Host": "192.168.123.199", "Port": 102, "Rack": 0, "Slot": 1, "Timeout": 30, "IdleTimeout": 30 } }, "autoEvents": [ { "interval": "10s", "onChange": false, "sourceName": "AllResource" } ] } } ]' 服务名称必须匹配/引用目标设备服务（“device-s7”），并且配置文件名称必须与前面步骤中的设备配置文件名称（“S7-Device”）匹配。 执行命令 现在我们准备运行一些命令。 查找可执行命令 使用以下查询查找可执行命令： curl http://localhost:59882/api/v3/device/name/S7-Device03 | json_pp { "apiVersion": "v3", "deviceCoreCommand": { "coreCommands": [ { "get": true, "name": "word", "parameters": [ { "resourceName": "word", "valueType": "Int16" } ], "path": "/api/v3/device/name/S7-Device03/word", "set": true, "url": "http://edgex-core-command:59882" }, { "get": true, "name": "int", "parameters": [ { "resourceName": "int", "valueType": "Int16" } ], "path": "/api/v3/device/name/S7-Device03/int", "set": true, "url": "http://edgex-core-command:59882" }, { "get": true, "name": "real", "parameters": [ { "resourceName": "real", "valueType": "Float32" } ], "path": "/api/v3/device/name/S7-Device03/real", "set": true, "url": "http://edgex-core-command:59882" }, { "get": true, "name": "heartbeat", "parameters": [ { "resourceName": "heartbeat", "valueType": "Int16" } ], "path": "/api/v3/device/name/S7-Device03/heartbeat", "set": true, "url": "http://edgex-core-command:59882" }, { "get": true, "name": "AllResource", "parameters": [ { "resourceName": "bool", "valueType": "Bool" }, { "resourceName": "byte", "valueType": "Uint8" }, { "resourceName": "word", "valueType": "Int16" }, { "resourceName": "dword", "valueType": "Int32" }, { "resourceName": "int", "valueType": "Int16" }, { "resourceName": "dint", "valueType": "Int32" }, { "resourceName": "real", "valueType": "Float32" }, { "resourceName": "heartbeat", "valueType": "Int16" } ], "path": "/api/v3/device/name/S7-Device03/AllResource", "set": true, "url": "http://edgex-core-command:59882" }, { "get": true, "name": "bool", "parameters": [ { "resourceName": "bool", "valueType": "Bool" } ], "path": "/api/v3/device/name/S7-Device03/bool", "set": true, "url": "http://edgex-core-command:59882" }, { "get": true, "name": "byte", "parameters": [ { "resourceName": "byte", "valueType": "Uint8" } ], "path": "/api/v3/device/name/S7-Device03/byte", "set": true, "url": "http://edgex-core-command:59882" }, { "get": true, "name": "dword", "parameters": [ { "resourceName": "dword", "valueType": "Int32" } ], "path": "/api/v3/device/name/S7-Device03/dword", "set": true, "url": "http://edgex-core-command:59882" }, { "get": true, "name": "dint", "parameters": [ { "resourceName": "dint", "valueType": "Int32" } ], "path": "/api/v3/device/name/S7-Device03/dint", "set": true, "url": "http://edgex-core-command:59882" } ], "deviceName": "S7-Device03", "profileName": "S7-Device" }, "statusCode": 200 } 执行设置命令 根据url和parameterNames执行 SET 命令，运行 SET 命令时将localhost替换为服务器 IP。 这里我们使用“heartbeat”命令： curl http://localhost:59882/api/v3/device/name/S7-Device03/heartbeat \ -H "Content-Type:application/json" -X PUT \ -d '{"heartbeat": "1"}' {"apiVersion":"v3","statusCode":200} 执行获取命令 运行 GET 命令时，将 localhost 替换为服务器 IP。 这里我们使用“heartbeat”命令： curl http://localhost:59882/api/v3/device/name/S7-Device03/heartbeat { "apiVersion": "v3", "statusCode": 200, "event": { "apiVersion": "v3", "id": "dd56ed66-2874-4d78-af02-753783164b3c", "deviceName": "S7-Device03", "profileName": "S7-Device", "sourceName": "heartbeat", "origin": 1702103303160428120, "readings": [ { "id": "8324105a-1843-415d-bea7-b61e6d12142c", "origin": 1702103303159722671, "deviceName": "S7-Device03", "resourceName": "heartbeat", "profileName": "S7-Device", "valueType": "Int16", "value": "1" } ] } } 自动事件 AutoEvent 在设备定义文件的 autoEvents 部分中定义： deviceList: autoEvents: interval: '30s' onChange: false sourceName: 'heartbeat' 服务启动后，查询 core-data API。 结果显示该服务每“30 秒”自动执行一次命令。 配置 该服务没有设备 SDK 提供的附加配置。 常用设备服务配置请参见设备服务配置部分。 协议属性 设备 S7 为 ISO-on-TCP 定义以下协议属性。 这些属性位于每个设备定义的协议部分中的“s7”键下。 Properity Default value Note Host N/A S7 ip address, e.g. 192.168.123.199 Port N/A S7 port, e.g. 102 Rack N/A Rack number, e.g. 0 Slot N/A Slot number, e.g. 1 Timeout 30 connect to S7 timeout, seconds IdleTimeout 30 connection idle timeout, seconds !!! example "S7 协议属性示例" ```json ... "protocols": { "s7": { "Host": "192.168.123.199", "Port": 102, "Rack": 0, "Slot": 1, "Timeout": 30, "IdleTimeout": 30 } } ... ``` API 参考 该服务继承了 SDK 中的通用设备服务 API API。 源代码 Device S7 的源代码可以在 https://github.com/edgexfoundry/device-s7 中找到。 额外细节 在 S7 设备资源使用带有“Int16”数字的“WORD”数据类型的用例中，“WORD”有两个字节，应转换为整数。 以下来自设备配置文件的摘录将“NodeName”DB4.DBW2 定义为“valueType”Int16： !!! example "示例 - 设备配置文件" ```yaml name: S7-Device manufacturer: YIQISOFT description: Example of S7 Device model: Siemens S7 labels: [ISO-on-TCP] deviceResources: - name: word description: PLC word isHidden: false properties: valueType: Int16 readWrite: RW attributes: NodeName: DB4.DBW2 ``` 读命令 Read Command 读取命令执行如下： Client 执行 Read Command； 设备服务发送 Read Command 读取一个‘WORD’数据； S7 设备返回一个两字节数据； 设备服务解析数据； 设备服务将数据转换为 Int16 值； 设备服务返回 json 格式给 Client。 graph LR A[Client] -->|1. Execute Read Command| B[Device Service] B -->|2. Send Request - WORD| C[S7 Device] C -->|3. Return 2 bytes| B B -->|4. Parse bytes| B B -->|5. Cast to Int16| B B -->|6. Return json| A 写命令 Write Command 写入命令执行如下： Client 执行 Write Command 写入一个 In16 值； 设备服务将 Int16 值转换为两个字节； 设备服务转换为二进制； 设备服务向 S7 设备发送写请求； 设备服务返回结果 json 给 Client。 graph LR A[Client] -->|1. Execute Write Command| B[Device Service] B -->|2. Cast to Int16| B B -->|3. Convert to binary| B B -->|4. Send Request - WORD| C[S7 Device] B -->|5. Return json| A 何时转换数据 您通常需要随时转换数据，因为 S7 设备仅接收其特定的数据类型。 支持的转换 支持的转换如下： From NodeName Bit(s) To valueType Address Sample Bool 1 Bool DB1.DBX0.0 Byte 8 Uint DB1.DBB1 Word 16 Int16 DB1.DBW2 DWord 32 Int32 DB1.DBD4 Int 16 Int16 DB1.DBW6 DInt 32 Int32 DB1.DBD8 Real 32 Float32 DB1.DBD20 "亿琪软件" 上海亿琪软件有限公司成立于 2016 年，专注于 5G 通信、AI 人工智能、边缘计算和大数据网络安全多项技术领域，致力于物联网领域前沿技术的创新，为用户提供全方位、智能化和安全的物联网解决方案。 2023 年，公司发布“YiFUSION ｜工业边缘智能融合一体机”产品，为工业客户提供一整套的边缘计算+AI 能力：高性能数据采集、多类型数据融合、AI 算法集成、云端业务对接。在边缘网关的基础上，集成了 IoT 平台的边缘协同能力、本地 Web SCADA 和 HMI 功能、本地数据存储、边缘 AI 视频分析、行业应用集成等。 2022 年，公司推出 “YiCLOUD ｜亿琪云”一站式物联网应用解决方案。公司的业务涵盖了智慧城市、智慧农业、智能工厂和智慧园区等多个领域，公司软硬件产品和解决方案获得华为技术认证，得到中国移动 OCP 认证，公司还是边缘计算产业联盟 ECC 成员。 "联系我们--商业服务" 网站：http://yiqisoft.cn 邮件：support@yiqisoft.cn 电话：021-68863086 手机：186-1666-9123
目录 01 介绍 02 技术要点 03 版本支持 04 产品应用 关于 亿琪软件 欢迎关注 EdgeX Foundry 中文社区公众号，及时获取最新资料和分享。 01 介绍 EdgeX Foundry 边缘计算框架的分层和服务为边缘设备/节点和云/企业应用之间提供了一个双向转换引擎。EdgeX 作为边缘计算平台是非常不错的选择。 S7 Micro Service - 用于通过 ISO-on-TCP 将西门子 S7（S7-200、S7-300、S7-400、S7-1200、S7-1500）设备连接到 EdgeX 的设备服务。 02 技术要点 工业互联网应用场景中，Siemens S7 PLC 是非常常见的工业控制设备，边缘计算框架 EdgeX 对于其驱动一直在 EdgeX Foundry 社区没有开源支持，我司经过项目的验证和长期的维护，保证了 S7 驱动的稳定性。 本开源 EdgeX 设备驱动采用了 Gos7(https://github.com/robinson/gos7) 底层驱动为基础，在基于 EdgeX device-sdk-go(https://github.com/edgexfoundry/device-sdk-go) 的框架下，完成了驱动的开发和验证。 03 版本支持 本次开源的 EdgeX 驱动支持 EdgeX v2.x（早期版本） 和 EdgeX v3.x（最新版本，且持续更新和维护）。 开源代码： EdgeX v2.x: https://github.com/yiqisoft/device-s7/tree/v2 EdgeX v3.x: https://github.com/edgexfoundry-holding/device-s7 04 产品应用 EdgeX 框架应用于我司的边缘计算产品 YiEDGE（边缘计算软件） 和 YiFUSION（工业边缘智能融合网关）。 YiFUSION: 边缘融合智能网关是指具备边缘计算、智能分析、数据融合等功能的智能网关，能够在边缘侧实现数据采集、处理、分析、融合和应用，为用户提供更加智能、高效和低成本的服务。 简洁定义 英文名称：YiFUSION 中文名称：工业边缘智能融合网关 产品形态：软硬件一体机 硬件架构：X86/ARM/超融合/国产化 软件架构：全微服务化 关于 亿琪软件 上海亿琪软件有限公司成立于2016年，专注于 5G 通信、AI 人工智能、边缘计算和大数据网络安全多项技术领域，致力于物联网领域前沿技术的创新，为用户提供全方位、智能化和安全的物联网解决方案。 2023年，公司发布“YiFUSION｜工业边缘智能融合一体机”产品，为工业客户提供一整套的边缘计算+AI能力：高性能数据采集、多类型数据融合、AI算法集成、云端业务对接。在边缘网关的基础上，集成了 IoT 平台的边缘协同能力、本地Web SCADA 和 HMI 功能、本地数据存储、边缘 AI 视频分析、行业应用集成等。 2022年，公司推出 “YiCLOUD｜亿琪云”一站式物联网应用解决方案。公司的业务涵盖了智慧城市、智慧农业、智能工厂和智慧园区等多个领域，公司软硬件产品和解决方案获得华为技术认证，得到中国移动OCP认证，公司还是边缘计算产业联盟ECC成员。 感知物联，畅快无限。 联系我们 网站：http://yiqisoft.cn 邮件：support@yiqisoft.cn 电话：021-68863086 手机：186-1666-9123
分享｜工业企业数字化转型之数据采集-西门子S7系列
目录 使用者 S7 ISO-on-TCP S7 协议配置 采集策略配置 注意事项 我司产品 产品白皮书 Modbus TCP 配置 PLC 支持 Modbus TCP 协议 配置网关 注意事项 开发者 关于 亿琪软件 西门子 S7 系列 PLC 是客户使用比较广泛且市场占有率非常高的工业现场智能自动化控制的设备，常见的型号有：S7-200 Smart, S7-300, S7-400, S7-1200, S7-1500 等。在这个系列的 PLC 中，使用比较多的数采协议有 S7 ISO-on-TCP 和 Modbus TCP，本文主要针对这两个协议进行讲解。 使用者 S7 ISO-on-TCP S7 ISO-on-TCP 以下简称 S7 协议，具体参考请到西门子官方网站查询，协议详解，并不是本文的重点内容。 S7 协议配置 首先，需要在 SIMATIC Portal 软件中将 S7 协议激活，当然，还需要配置一下具体可以支持的最大连接数，可以参考其他网站的配置手册。 其次，需要配置 PLC 设备本身的 IP 地址和端口号，默认端口号是 TCP:102； 使用相关的网关设备采集数据，需要默认配置4个参数，分别是： IP 地址：192.168.1.1 端口号：102 RACK：0 SLOT：1 以上配置完成后，如果顺利的话，应该可以直接根据 Portal 里面的点位表获取你所需要的点位数据值。 采集策略配置 首先，你需要了解 PLC 的工作原理，知道点位的缩写形式： DB1.DBX0.0：其代表的含义是 DB1 槽位，DBX0.0 是布尔型 0 寄存器的 0 位； DB3.DBD12：其代表了 DB3 槽位，DBD12 是 DWORD 12 寄存器； 其他不再举例，如果你看不懂的话，可能需要请教专业人士； 其次，需要将 PLC 获取来的数据与网关所在的系统进行数据类型的转化： bool 对应 布尔型； real 对应 Float32； 以此类推，不再举例； 然后，就是对应的采集策略和频率，具体要看业务的需要，设置合适的参数来。 注意事项 本采集 PLC 有连接数限制，一般不超过 8 个 TCP 连接； 每个连接所能承载的每个数据包的大小，有可能会出现 PDU 错误，这个需要询问采集设备厂家的工程师； 了解每个点位的采集反馈时间，据我们测算，1-3ms 是比较正常的，如果连续读取多个，要看是不是在你业务所要求的延迟范围内； 要观察 Portal 里面 PLC 设备的 CPU 和内存使用率，不要因为数据采集导致其本身业务发生问题； 其他问题，大部分是网络、配置点位 错误导致。 我司产品 亿琪软件公司针对大数据量、高性能采集方面，做了软件优化，我们的一体化网关可以最多 1秒内采集超过20000个数据点位。 工业边缘智能融合一体机产品 产品白皮书 Modbus TCP 配置 PLC 支持 Modbus TCP 协议 网上有很多配置手册可以参考，主要是将需要的 DB 段映射到 Modbus 服务上即可。 配置网关 大部分数据采集网关都能很好的支持 Modbus 协议，也不是非常复杂，建议自己多尝试。 注意事项 首先，Modbus TCP 的效率不如 S7 本身协议； Modbus 协议比较通用，业务不复杂的情况下，首选推荐； Modbus 协议对 PLC 的 CPU 和内存消耗较大，高性能的情况下慎选； PLC 支持的 Modbus 只有一个客户端可以连接，切记。 开发者 如果你在针对 S7 协议进行一些高性能开发的话，遇到问题可以通过这个文章进行排查和自我实践：PLC | 西门子 Siemens S7 ISO-on-TCP 通讯协议探究——提高数据采集效率故障分析（使用边缘计算网关） 关于 亿琪软件 上海亿琪软件有限公司成立于2016年，专注于 5G 通信、AI 人工智能、边缘计算和大数据网络安全多项技术领域，致力于物联网领域前沿技术的创新，为用户提供全方位、智能化和安全的物联网解决方案。 2023年，公司发布“YiFUSION｜工业边缘智能融合一体机”产品，为工业客户提供一整套的边缘计算+AI能力：高性能数据采集、多类型数据融合、AI算法集成、云端业务对接。在边缘网关的基础上，集成了 IoT 平台的边缘协同能力、本地Web SCADA 和 HMI 功能、本地数据存储、边缘 AI 视频分析、行业应用集成等。 2022年公司推出 “YiCLOUD｜亿琪云”一站式物联网应用解决方案。公司的业务涵盖了智慧城市、智慧农业、智能工厂和智慧园区等多个领域，公司软硬件产品和解决方案获得华为技术认证，得到中国移动OCP认证，公司还是边缘计算产业联盟ECC成员。 感知物联，畅快无限。 联系我们 网站：http://yiqisoft.cn 邮件：support@yiqisoft.cn 电话：021-68863086 手机：186-1666-9123
PLC | 西门子 Siemens S7 ISO-on-TCP 通讯协议探究——提高数据采集效率故障分析（使用边缘计算网关）
目录 需求/故障现场 分析过程 winCC 数据采集抓包 分析过程1：采集20个 real 数据字段 分析过程2：采集10个 word 数据字段 自有软件数据采集抓包 每次只是读取了1个 word 数据字段 解决方案构思 验证 读取1000个字节 下一步是继续验证分多个 item 进行数据采集 winCC 数据格式 自己代码 开发过程 大概过程描述 总结 效果展示 改进？ 解决方案 关于 亿琪软件 众所周知，我们软件读取 PLC 数据时按照 Bool/Byte/Word/Real 等类型进行通讯，有时候，需要频繁读取 PLC 多个数据字段偏移量时，就会造成传输效率低下的问题。 需求/故障现场 PLC 上有 100 个 word 需要读取，偏移量顺序排列，比如：从 0 - 200； 需要 1 秒读取 1 次数据； 转换后，数据转发到第三方系统：MQTT，SQL等； 逐个读取每个 word，两个字节，需要在一个 TCP 会话中执行 100 次请求； 每次请求，三个 TCP 数据传输，每次需要 15ms（423行-421行：3.614448-3.598902=0.015546s）； 这样的话，100次请求需要1.5546s，算上网络延迟和处理性能问题，整个过程需要2秒以上； 结果就是：完全达不到 1秒1次 采集的需求。 分析过程 winCC 数据采集抓包 分析过程1：采集20个 real 数据字段 winCC 将数据包分解成 3个 item 分析过程2：采集10个 word 数据字段 同样原理，winCC 将数据包按照每个 item 32 个字节 自有软件数据采集抓包 每次只是读取了1个 word 数据字段 解决方案构思 每次按照要求，获取所有需要的数据偏移量； 取回来后，按照测点要求，自己根据数据类型分解出来； 循环读取下一次数据； 验证 读取1000个字节 可以看到分了5次数据，222+222+222+222+112=1000 下一步是继续验证分多个 item 进行数据采集 winCC 数据格式 效率高，每次只需要 <2ms，分析原因：每次读取都是连续的地址空间，不需要PLC进行分段读取； 自己代码 效率低，每次需要20-50ms，分析原因：每个 item 里面只有一个测点（word类型），需要分段读取； 开发过程 大概过程描述 由于每次请求的数据量（按测点）叠加在一起，通过 S7DataItem 来组合，最多20个 item，打包一起发送到 PLC； 收到每次的返回数据，再解析成对象插入二维表，等待处理； 全部处理完成，统一根据请求数量，返回相应的结果集； 总结 PLC 针对于每个测点的处理时间在 1-3秒，数量越多，时间越长，是累加的； 100个测点，算上 TCP 包头和包尾，大概来回数据时间是 220ms左右，200个测点是 400ms左右； 通过这种方式，一个 PLC 建议采集点不超过 500个，虽然对 PLC 性能影响不大，但是处理时间较长，不适用1秒一次采集需求； 每个型号 PLC 的处理性能不一样，支持的 TCP 连接数也不一定一样，所以，要根据具体需求来决定。 效果展示 存入 SQL 数据库，完全控制在1秒一次采集 4 个 TCP 连接非常稳定 网关性能稳定 与 PLC 交互的网卡网络流量很少 改进？ 类似 winCC 的模式，一次性读取一段偏移量，节省 TCP 开销，也节省 PLC 处理每个测点； 针对一次读取来的一段偏移量内容进行解析，需要对字节码流处理非常熟悉； 对于新建项目，比较适合用改进的方法，毕竟 PLC 可以根据需求改动测点偏移量； 解决方案 关于 亿琪软件 上海亿琪软件有限公司成立于2016年，专注于 5G 通信、AI 人工智能、边缘计算和大数据网络安全多项技术领域，致力于物联网领域前沿技术的创新，为用户提供全方位、智能化和安全的物联网解决方案。 2023年，公司发布“YiFUSION｜工业边缘智能融合一体机”产品，为工业客户提供一整套的边缘计算+AI能力：高性能数据采集、多类型数据融合、AI算法集成、云端业务对接。在边缘网关的基础上，集成了 IoT 平台的边缘协同能力、本地Web SCADA 和 HMI 功能、本地数据存储、边缘 AI 视频分析、行业应用集成等。 2022年公司推出 “YiCLOUD｜亿琪云”一站式物联网应用解决方案。公司的业务涵盖了智慧城市、智慧农业、智能工厂和智慧园区等多个领域，公司软硬件产品和解决方案获得华为技术认证，得到中国移动OCP认证，公司还是边缘计算产业联盟ECC成员。 感知物联，畅快无限。 联系我们 网站：http://yiqisoft.cn 邮件：support@yiqisoft.cn 电话：021-68863086 手机：186-1666-9123
PLC | YiEDGE边缘计算（网关）框架使用 Gos7 与 西门子 PLC 通讯
目录 理解 Gos7 API 结构 Client API API AG(Automatisationsgerät) API PG(Programmiergerät) Helper API PLC 数据交互步骤 基于 EdgeX Foundry 的 S7 device service 驱动已开源 关于 亿琪软件 Golang 作为高性能编程语言，在边缘计算领域越来越流行，编译完超小的二进制，打包成 docker image 作为微服务框架在边缘计算领域是最佳选择。 Gos7 作为 Golang 原生的 S7 PLC 对接实现是非常不错的选择，本文将简单介绍 Gos7 在边缘计算框架 YiEDGE 中的使用。 上一篇文章“PLC｜Golang 连接 Siemens S7/TCP 协议读取数据”介绍了如何独立使用 Gos7 与 PLC通讯，作为基础，你应该有所熟悉了。 理解 Gos7 API 结构 Client API API AG(Automatisationsgerät) AG 相关的 API 主要是负责 PLC 读取/写入数据，对应的 PLC 内部，最常用的应该是：DB 段。 Read/Write IPU (AB) Read/Write IPI (EB) Read/Write Merkers(MB) Read/Write Data Block (DB) Read/Write Timer (TM) Read/Write Counter (CT) Multiple Read/Write Area Get Block Info /***************start API AG (Automatisationsgerät)***************/ //Read data blocks from PLC AGReadDB(dbNumber int, start int, size int, buffer []byte) (err error) //write data blocks into PLC AGWriteDB(dbNumber int, start int, size int, buffer []byte) (err error) //Read Merkers area from PLC AGReadMB(start int, size int, buffer []byte) (err error) //Write Merkers from into PLC AGWriteMB(start int, size int, buffer []byte) (err error) //Read IPI from PLC AGReadEB(start int, size int, buffer []byte) (err error) //Write IPI into PLC AGWriteEB(start int, size int, buffer []byte) (err error) //Read IPU from PLC AGReadAB(start int, size int, buffer []byte) (err error) //Write IPU into PLC AGWriteAB(start int, size int, buffer []byte) (err error) //Read timer from PLC AGReadTM(start int, size int, buffer []byte) (err error) //Write timer into PLC AGWriteTM(start int, size int, buffer []byte) (err error) //Read counter from PLC AGReadCT(start int, size int, buffer []byte) (err error) //Write counter into PLC AGWriteCT(start int, size int, buffer []byte) (err error) //multi read area AGReadMulti(dataItems []S7DataItem, itemsCount int) (err error) //multi write area AGWriteMulti(dataItems []S7DataItem, itemsCount int) (err error) /*block*/ DBFill(dbnumber int, fillchar int) error DBGet(dbnumber int, usrdata []byte, size int) error //general read function with S7 sytax Read(variable string, buffer []byte) (value interface{}, err error) //Get block infor in AG area, refer an S7BlockInfor pointer GetAgBlockInfo(blocktype int, blocknum int) (info S7BlockInfo, err error) /***************end API AG***************/ API PG(Programmiergerät) PG 相关的 API 主要是针对 PLC 本体的一些启停、设备信息读取、时钟读写等。 /***************start API PG (Programmiergerät)***************/ /*control*/ //Hotstart PLC, Puts the CPU in RUN mode performing an HOT START. PLCHotStart() error //Cold start PLC, change CPU into runmode performing and COLD START PLCColdStart() error //change CPU to stop mode PLCStop() error //return CPU status: running/stopped PLCGetStatus() (status int, err error) /*directory*/ //list all blocks in PLC, return a Blockslist which contains list of OB, DB, ... PGListBlocks() (list S7BlocksList, err error) /*security*/ //set the session password for PLC to meet its security level SetSessionPassword(password string) error //clear the password set for current session ClearSessionPassword() error //return the CPU protection level info, refer to: §33.19 of "System Software for S7-300/400 System and Standard Functions" //return S7Protection and its properties. GetProtection() (protection S7Protection, err error) /*system information*/ //get CPU order code, return S7OrderCode GetOrderCode() (info S7OrderCode, err error) //get CPU info, return S7CpuInfo and its properties GetCPUInfo() (info S7CpuInfo, err error) //get CP info, return S7CpInfo and its properties GetCPInfo() (info S7CpInfo, err error) /*datetime*/ //read clock on PLC, return a time PGClockRead(datetime time.Time) error //write clock to PLC with datetime input PGClockWrite() (dt time.Time, err error) /***************end API AG***************/ Helper API Helper API 主要负责从 buffer 中读取/写入指定的数据类型到变量中。 Read/Write a boolean Read/Write a value(int) Read/Write a float (Real) Read/Write chars ... 等，各种数据格式。 PLC 数据交互步骤 创建 PLC TCP 连接 根据测点 command 读取/写入偏移量 返回结果数据 基于 EdgeX Foundry 的 S7 device service 驱动已开源 https://www.yiqisoft.cn/blogs/edgex/517.html 关于 亿琪软件 上海亿琪软件有限公司成立于2016年，专注于 5G 通信、AI 人工智能、边缘计算和大数据网络安全多项技术领域，致力于物联网领域前沿技术的创新，为用户提供全方位、智能化和安全的物联网解决方案。 2023年，公司发布“YiFUSION｜工业边缘智能融合一体机”产品，为工业客户提供一整套的边缘计算+AI能力：高性能数据采集、多类型数据融合、AI算法集成、云端业务对接。在边缘网关的基础上，集成了 IoT 平台的边缘协同能力、本地Web SCADA 和 HMI 功能、本地数据存储、边缘 AI 视频分析、行业应用集成等。 2022年公司推出 “YiCLOUD｜亿琪云”一站式物联网应用解决方案。公司的业务涵盖了智慧城市、智慧农业、智能工厂和智慧园区等多个领域，公司软硬件产品和解决方案获得华为技术认证，得到中国移动OCP认证，公司还是边缘计算产业联盟ECC成员。 感知物联，畅快无限。 联系我们 网站：http://yiqisoft.cn 邮件：support@yiqisoft.cn 电话：021-68863086 手机：186-1666-9123
目录 Siemens S7 PLC S7 protocol in Golang 编写自己的代码 基于 EdgeX Foundry 的 S7 device service 驱动已开源 关于 亿琪软件 欢迎关注 EdgeX Foundry 中文社区公众号(边缘计算社区)，及时获取最新资料和分享。 工业项目中，工业现场很多情况是 Siemens S7 系列 PLC，通过应用程序读取信息已经是非常迫切的一些需求，尤其是在需要边缘计算网关的环境下，与外部系统对接的时候，这些都是基础性功能。 Siemens S7 PLC 笔者使用 SIMATIC S7-1200，CPU 是 1211C，6ES7 211-1AE40-0XB0，没有使用扩展模块，只是为了测试连通性。 使用 Step 7 V14 PORTAL 配置好运行环境； 配置少许几个测点，能通过 Modbus TCP 获取数据； 打开 S7 get/put 功能接口； 确认 TCP:102 端口能够正常连接； 少量了解 PLC 工作机制，S7 协议数据格式； S7 protocol in Golang 笔者使用 Gos7 库，参考地址如下：https://github.com/robinson/gos7； 熟读库中的源码，熟悉 test 目录下例子 API 的使用； 使用 /test 目录下测试例子跑通于 PLC 的基础连接； 运行 test 效果如下： Running tool: /opt/homebrew/bin/go test -timeout 30s -run ^TestTCPClient$ plcProj tcp: 2023/03/22 13:52:37 s7: sending 03 00 00 16 11 e0 00 00 00 01 00 c0 01 0a c1 02 01 00 c2 02 01 01 tcp: 2023/03/22 13:52:37 s7: received 03 00 00 16 11 d0 00 01 00 01 00 c0 01 0a c1 02 01 00 c2 02 01 01 tcp: 2023/03/22 13:52:37 s7: sending 03 00 00 19 02 f0 80 32 01 00 00 04 00 00 08 00 00 f0 00 00 01 00 01 01 e0 tcp: 2023/03/22 13:52:37 s7: received 03 00 00 1b 02 f0 80 32 03 00 00 04 00 00 08 00 00 00 00 f0 00 00 01 00 01 00 f0 tcp: 2023/03/22 13:52:37 s7: sending 03 00 00 2d 02 f0 80 32 01 00 00 05 00 00 0e 00 0e 05 01 12 0a 10 02 00 0a 00 02 84 00 00 00 00 04 00 50 00 64 00 00 00 00 00 00 00 00 tcp: 2023/03/22 13:52:37 s7: received 03 00 00 16 02 f0 80 32 03 00 00 05 00 00 02 00 01 00 00 05 01 ff tcp: 2023/03/22 13:52:37 s7: sending 03 00 00 1f 02 f0 80 32 01 00 00 05 00 00 0e 00 00 04 01 12 0a 10 02 00 0a 00 02 84 00 00 00 tcp: 2023/03/22 13:52:37 s7: received 03 00 00 23 02 f0 80 32 03 00 00 05 00 00 02 00 0e 00 00 04 01 ff 04 00 50 3a 98 00 00 00 00 42 c8 00 00 编写自己的代码 自己的测试源码，获取 偏移量 160 的 WORD 数据（此处是用 clock 时钟模拟） package main import ( "fmt" "time" "github.com/robinson/gos7" ) type PlcData struct { intValue uint16 } func main() { const ( ipAddr = "192.168.123.199" //PLC IP rack = 0 // PLC机架号 slot = 1 // PLC插槽号 ) //PLC tcp连接客户端 handler := gos7.NewTCPClientHandler(ipAddr, rack, slot) //连接及读取超时 handler.Timeout = 200 * time.Second //关闭连接超时 handler.IdleTimeout = 200 * time.Second //打开连接 handler.Connect() //函数退出时关闭连接 defer handler.Close() //获取PLC对象 client := gos7.NewClient(handler) //DB号 address := 1 //起始地址 start := 160 //读取字节数 size := 2 //读写字节缓存区 buffer := make([]byte, size) //读取字节 client.AGReadDB(address, start, size, buffer) //gos7解析数据类 var helper gos7.Helper //gos7内置方法解析数据 var data PlcData helper.GetValueAt(buffer[0:2], 0, &data.intValue) //输出数据 fmt.Println(data) fmt.Println(buffer) } 编译，运行： jiekechoo@jiekechoo GoS7Demo % go build && ./plcProj {26} [0 26] jiekechoo@jiekechoo GoS7Demo % go build && ./plcProj {27} [0 27] 基于 EdgeX Foundry 的 S7 device service 驱动已开源 https://www.yiqisoft.cn/blogs/edgex/517.html 关于 亿琪软件 上海亿琪软件有限公司成立于2016年，专注于 5G 通信、AI 人工智能、边缘计算和大数据网络安全多项技术领域，致力于物联网领域前沿技术的创新，为用户提供全方位、智能化和安全的物联网解决方案。 2023年，公司发布“YiFUSION｜工业边缘智能融合一体机”产品，为工业客户提供一整套的边缘计算+AI能力：高性能数据采集、多类型数据融合、AI算法集成、云端业务对接。在边缘网关的基础上，集成了 IoT 平台的边缘协同能力、本地Web SCADA 和 HMI 功能、本地数据存储、边缘 AI 视频分析、行业应用集成等。 2022年公司推出 “YiCLOUD｜亿琪云”一站式物联网应用解决方案。公司的业务涵盖了智慧城市、智慧农业、智能工厂和智慧园区等多个领域，公司软硬件产品和解决方案获得华为技术认证，得到中国移动OCP认证，公司还是边缘计算产业联盟ECC成员。 感知物联，畅快无限。 联系我们 网站：http://yiqisoft.cn 邮件：support@yiqisoft.cn 电话：021-68863086 手机：186-1666-9123