【Python】Modbus 设备批量模拟

由于某些时候需要大量模拟Modbus设备对边缘网关进行压力测试,
使用Modbus模拟工具太麻烦且寄存器值无法自动递增,于是我们可以使用python来解决此问题。
以下代码可直接复制使用。
from pymodbus.server.sync import StartTcpServer, ModbusTcpServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock, ModbusSlaveContext, ModbusServerContext
from pymodbus.transaction import ModbusSocketFramer
import logging
import threading
import socket

# 配置日志
logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger('pymodbus')
log.setLevel(logging.DEBUG)

# 创建一个自动递增的寄存器值
def create_auto_increment_block(start_value, size):
    log.debug(f"Creating auto increment block with start value {start_value} and size {size}")
    return ModbusSequentialDataBlock(0, [start_value + i for i in range(size)])

# 初始化数据存储区
store = ModbusSlaveContext(
    di=ModbusSequentialDataBlock(0, [0]*10),  # 离散输入 (示例值)
    co=ModbusSequentialDataBlock(0, [0]*10),  # 线圈 (示例值)
    hr=create_auto_increment_block(0, 100),   # 保持寄存器
    ir=ModbusSequentialDataBlock(0, [0]*10)   # 输入寄存器 (示例值)
)

context = ModbusServerContext(slaves=store, single=True)

# 设置设备标识
identity = ModbusDeviceIdentification()
identity.VendorName = 'pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/riptideio/pymodbus/'
identity.ProductName = 'pymodbus Server'
identity.ModelName = 'pymodbus Server'
identity.MajorMinorRevision = '1.0'

class CustomModbusTcpServer(ModbusTcpServer):

    def handle(self):
        try:
            log.debug(f"Client Connected [{self.client_address}]")
            super().handle()
        except Exception as e:
            log.error(f"Error handling client {self.client_address}: {e}")
        finally:
            log.debug(f"Client Disconnected [{self.client_address}]")

def run_server(port):
    log.debug(f"Starting Modbus TCP server on port {port}...")
    try:
        server = CustomModbusTcpServer(context, identity=identity, address=("10.245.3.9", port), framer=ModbusSocketFramer)
        server.serve_forever()
    except Exception as e:
        log.error(f"Error starting Modbus TCP server on port {port}: {e}")
    log.debug(f"Modbus TCP server on port {port} is running.")

# 在单独的线程中启动服务器
for port in range(502, 602):  # 从502到601共100个端口
    server_thread = threading.Thread(target=run_server, args=(port,))
    server_thread.start()

# 确保代码执行到这里
print("Modbus TCP servers setup initiated.")

# 确认端口是否绑定成功
for port in range(502, 602):  # 从502到601共100个端口
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    result = sock.connect_ex(('10.245.3.9', port))
    if result == 0:
        print(f"Port {port} is open and listening.")
    else:
        print(f"Port {port} is not open.")
    sock.close()

说明:
1、10.245.3.9为本地电脑IP地址;
2、模拟端口从502到601共100个端口;
3、模拟的每台设备有100个寄存器,默认寄存器值自动递增;

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值