映翰通IG502实战:使用DSA自定义快函数,通过TCP转发采集数据

在这里插入图片描述

前言

在工业现场项目中,边缘网关通常负责采集PLC、仪表和传感器的数据。完成南向采集后,有时需要把实时数据直接发送到客户自己的服务器,由服务器进行存储、展示或二次处理。

本文使用InHand IG502网关,通过DeviceSupervisor Agent(以下简称DSA)采集Modbus数据,再使用“自定义快函数”编写Python脚本,将采集结果通过TCP发送到电脑。

电脑端使用HERCULES作为TCP Server接收数据。本文将从测试环境、网络拓扑、HERCULES配置、DSA配置、完整脚本及常见问题排查几个方面,记录整个验证过程。


一、测试目标

本次需要验证的数据链路为:

Modbus设备
    ↓
IG502上的DSA采集数据
    ↓
DSA本地消息总线
    ↓
自定义快函数获取采集结果
    ↓
Python socket建立TCP连接
    ↓
电脑上的HERCULES接收数据

测试完成后,电脑端应能够持续收到IG502转发的JSON格式采集数据。


二、测试环境

本次使用的测试环境如下:

项目配置
边缘网关InHand IG502
边缘应用DeviceSupervisor Agent(DSA)
南向采集协议Modbus RTU
测试测点temphumidity
电脑IP地址10.5.60.9
TCP服务端口3699
电脑端测试工具HERCULES SETUP Utility 3.2.8

IG502和电脑连接到同一个Wi-Fi网络,可以互相Ping通。

> 【拓扑图位置:上传并插入 】

需要注意:能够Ping通只代表基本网络可达,并不能证明TCP 3699端口一定可以建立连接。防火墙、端口监听状态和脚本配置仍需单独检查。


三、确认DSA已经采集到数据

在配置TCP转发前,应先确认DSA能够正常读取现场设备的数据。

登录IG502管理页面,进入:

边缘计算 → 设备监控 → 测点监控

重点检查以下内容:

  1. 控制器处于在线状态。
  2. 测点左侧显示绿色状态。
  3. 测点数值能够正常显示。
  4. 测点采集时间持续更新。

本次测试使用两个测点:

测点名称数据类型地址分组
tempFLOAT40001default
humidityWORD40002default

如果“测点监控”页面本身没有实时数据,应先检查Modbus参数、串口参数、从站地址、寄存器地址和数据类型。只有南向采集正常后,后续脚本才能获得有效数据。

> 【插图位置1:DSA测点监控页面,显示控制器和测点正常在线】


四、配置HERCULES TCP Server

HERCULES是一款常用的串口和网络调试工具。本次使用它在电脑上建立TCP Server,用来接收IG502发送的数据。

可以从HW-group官方网站下载HERCULES SETUP Utility。

下载并运行HERCULES后,按照以下步骤配置:

  1. 打开TCP Server选项卡。
  2. Port中填写3699
  3. 启动TCP Server。
  4. 按钮显示为Close时,表示端口已经开始监听。
  5. 测试过程中保持HERCULES运行。

如果Windows弹出防火墙提示,应允许HERCULES通过当前使用的专用网络。也可以在Windows防火墙中单独创建一条入站规则,放行TCP 3699端口。

在这里插入图片描述

为什么Clients count可能一直是0

本文脚本采用短连接方式:

收到一条采集消息
    ↓
建立TCP连接
    ↓
发送数据
    ↓
关闭TCP连接

每次连接持续时间很短,因此即使数据已经发送成功,HERCULES中的Clients count也可能显示为0

判断是否接收成功时,应主要观察Received data区域是否出现数据。


五、先用固定字符串验证TCP链路

首次测试时,不建议直接发送采集数据。可以先创建一个周期触发快函数,每隔几秒发送一次固定字符串。

这样可以快速确认:

  • IG502能够访问电脑IP;
  • HERCULES正在监听3699端口;
  • Windows防火墙没有拦截连接;
  • DSA自定义快函数可以正常执行;
  • Python脚本可以建立TCP连接并发送数据。

进入:

边缘计算 → 设备监控 → 自定义快函数

新增快函数并配置:

参数配置
名称tcp_test
启用
模式周期触发
周期5秒
入口函数main

测试脚本如下:

import socket
from common.Logger import logger

SERVER_IP = "10.5.60.9"
SERVER_PORT = 3699

def main():
    tcp_client = None

    try:
        logger.info("Starting TCP test")

        tcp_client = socket.socket(
            socket.AF_INET,
            socket.SOCK_STREAM
        )
        tcp_client.settimeout(5)
        tcp_client.connect((SERVER_IP, SERVER_PORT))

        message = "IG502 TCP test\r\n"
        tcp_client.sendall(message.encode("utf-8"))

        logger.info("TCP test sent successfully")

    except Exception as e:
        logger.error("TCP test failed: %s" % str(e))

    finally:
        if tcp_client:
            tcp_client.close()

保存并启用后,HERCULES的Received data区域应每5秒出现一次:

IG502 TCP test

在这里插入图片描述

周期触发的入口函数

周期触发不会向入口函数传入采集消息,因此函数必须写成:

def main():

如果函数定义中增加了不需要的参数,脚本运行时就会出现参数缺失错误。


六、订阅DSA消息并发送真实采集数据

固定字符串测试成功后,说明TCP链路已经正常。接下来配置真实采集数据转发。

可以重新创建一个自定义快函数,配置如下:

参数配置
名称tcp_forward
启用
模式本地订阅消息触发
订阅Topicds2/eventbus/south/read/+
入口函数main

ds2/eventbus/south/read/+是DSA南向驱动发布控制器采集结果的消息主题。每完成一轮数据采集,订阅该主题的快函数就会被触发一次。

在这里插入图片描述

完整脚本

import json
import socket
from common.Logger import logger

# TCP服务器的IP地址
SERVER_IP = "10.5.60.9"

# TCP服务器监听端口
SERVER_PORT = 3699

def main(payload):
    tcp_client = None

    try:
        logger.info("Received payload: %s" % payload)

        # 将DSA采集结果统一转换为bytes
        if isinstance(payload, bytes):
            message = payload
        elif isinstance(payload, str):
            message = payload.encode("utf-8")
        else:
            message = json.dumps(
                payload,
                ensure_ascii=False
            ).encode("utf-8")

        # 每条消息增加换行,方便接收端区分和显示
        message += b"\r\n"

        tcp_client = socket.socket(
            socket.AF_INET,
            socket.SOCK_STREAM
        )
        tcp_client.settimeout(5)
        tcp_client.connect((SERVER_IP, SERVER_PORT))
        tcp_client.sendall(message)

        logger.info("Collected data sent successfully")

    except Exception as e:
        logger.error("TCP send failed: %s" % str(e))

    finally:
        if tcp_client:
            tcp_client.close()

保存并启用后,只要DSA继续采集数据,HERCULES就会持续收到JSON内容。

在这里插入图片描述

收到的数据结构类似:

{
  "controllers": [
    {
      "name": "saas",
      "health": 1,
      "timestamp": 1785378505,
      "measures": [
        {
          "name": "temp",
          "health": 1,
          "timestamp": 1785378505,
          "timestampMsec": 1785378505620,
          "measureIndex": 0,
          "rawbytes": "",
          "value": 0.0
        },
        {
          "name": "humidity",
          "health": 1,
          "timestamp": 1785378505,
          "timestampMsec": 1785378505620,
          "measureIndex": 1,
          "rawbytes": "",
          "value": 0
        }
      ]
    }
  ]
}

实际字段和数值会根据控制器、测点及DSA版本发生变化。


七、关键问题:入口函数参数

测试过程中,脚本最初写成:

def main(topic, payload):

DSA日志反复出现:

The script may run incorrectly
(main() missing 1 required positional argument: 'payload')

这条日志说明,当前IG502上的DSA在触发这个本地订阅快函数时,只传入了一个参数。

因此,本次测试环境中正确的函数定义为:

def main(payload):

修改入口函数后,采集数据立即成功发送到HERCULES。

不同DSA版本、不同快函数类型的入口参数可能存在差异。配置时应结合当前版本的默认示例和实际日志判断。

可以记住本文中的两个入口形式:

触发模式入口函数
周期触发def main():
本地订阅消息触发def main(payload):

八、如何通过日志判断问题

DSA日志是排查自定义快函数问题最直接的方式。

1. TCP发送成功

Received payload: ...
Collected data sent successfully

说明脚本已经获得采集消息,并完成TCP发送。

2. 连接被拒绝

Connection refused

通常表示电脑IP可以到达,但目标端口没有服务监听。检查:

  • HERCULES是否运行;
  • 是否选择了TCP Server
  • 监听端口是否为3699;
  • 脚本端口是否与HERCULES一致。

3. 连接超时

timed out

常见原因包括:

  • SERVER_IP填写错误;
  • IG502到电脑的路由不通;
  • Windows防火墙拦截TCP 3699;
  • 网络启用了客户端隔离;
  • 服务器端口没有正确放行。

4. 入口函数缺少参数

missing required positional argument

说明触发模式与函数定义不匹配。检查当前使用的是周期触发还是本地订阅消息触发,并按照本文对应的函数形式修改。

5. 日志没有Received payload

如果脚本编译成功,但一直没有出现:

Received payload

应检查:

  1. 快函数是否已经启用;
  2. 模式是否为“本地订阅消息触发”;
  3. Topic是否为ds2/eventbus/south/read/+
  4. 入口函数是否填写为main
  5. 测点监控页面是否持续产生采集数据。

九、局域网测试注意事项

本文中IG502和电脑连接同一个Wi-Fi,能够互相Ping通。

如果现场采用类似架构,还需要关注以下事项:

  1. 确认电脑当前实际使用的无线网卡IP。
  2. 不要误填电脑的虚拟网卡、VPN网卡或有线网卡IP。
  3. 确认无线网络没有开启客户端隔离。
  4. 确认电脑系统防火墙允许TCP 3699入站。
  5. 确认HERCULES保持监听状态。

脚本中的目标地址应填写电脑在该网络中的实际地址:

SERVER_IP = "10.5.60.9"
SERVER_PORT = 3699

如果电脑IP由DHCP自动分配,地址可能在重新连接网络后发生变化。长期运行时,建议为电脑配置固定地址或DHCP地址保留。


十、正式项目中的优化建议

本文脚本用于功能验证,采用每条数据建立一次TCP连接的方式,逻辑简单且方便排查。

正式项目中还可以根据实际需求增加:

  1. 断线重连;
  2. 失败重试和重试间隔;
  3. 本地缓存,避免网络中断时丢失数据;
  4. 长连接和心跳检测;
  5. 消息长度或结束符定义;
  6. 数据序号和时间戳;
  7. 服务端响应确认;
  8. 身份认证和传输加密;
  9. 日志大小和输出频率控制。

TCP本身只负责传输字节流,不会自动划分消息边界。本文通过:

message += b"\r\n"

为每条消息增加换行符,方便HERCULES显示。正式项目中,客户端和服务器应提前约定清晰的消息边界规则。


十一、总结

本文完成了以下验证:

IG502采集Modbus数据
    ↓
DSA发布南向采集消息
    ↓
自定义快函数接收payload
    ↓
Python socket连接电脑TCP 3699
    ↓
HERCULES成功接收JSON数据

整个过程中最重要的几点是:

  1. 先在测点监控页面确认南向采集正常。
  2. 先使用固定字符串验证TCP链路,再转发真实数据。
  3. 周期触发使用main()
  4. 本文设备的本地订阅消息触发使用main(payload)
  5. Ping通不代表TCP端口一定可用。
  6. 通过DSA日志可以快速判断是触发、参数还是网络问题。

按照这种分阶段验证方式,可以较快地完成IG502采集数据到自建TCP服务器的联调。


InHand IG502 DSA DeviceSupervisor 工业网关 Python TCP Modbus 边缘计算 工业物联网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值