python - pymodbus 如何通过真实的串行端口测试我的串行 RTU 服务器
问题描述
我尝试为我的 pymodbus RTU 服务器编写一个 pytest,我想将 32 位浮点编码值写入服务器并将其与服务器自己的寄存器读取方法进行比较。服务器看起来像这样:
class ModbusRTUServer:
P_target_address = 0x33
def __init__(self, port, timeout, baudrate):
self.thread = None
self.port = port
self.timeout = timeout
self.baudrate = baudrate
self.block = ModbusSequentialDataBlock.create()
self.store = ModbusSlaveContext(hr=self.block, ir=self.block)
self.context = ModbusServerContext(slaves=self.store)
self.P_target = 0
def _run_server_threaded(self):
StartSerialServer(
self.context,
framer=ModbusRtuFramer,
port=self.port,
timeout=self.timeout,
baudrate=self.baudrate,
)
l.debug("StartSerialServer() ended.")
def run_server(self):
self.thread = Thread(target = self._run_server_threaded)
self.thread.start()
def stop_server(self):
StopServer()
def get_P_target_float32(self):
return BinaryPayloadDecoder.fromRegisters(
self.block.getValues(ModbusRTUServer.P_target_address, 2),
byteorder=Endian.Big, wordorder=Endian.Big
).decode_32bit_float()
这是测试,它不起作用:
@patch("twisted.internet.serialport.SerialPort")
def test_modbus_rtu_server_get_P_target_float32_should_be_big_endian_encoded(mock_sp) -> None:
with patch('twisted.internet.reactor') as mock_reactor:
m, s = os.openpty()
server = ModbusRTUServer(os.ttyname(s), test_server_timeout, test_server_baudrate)
server.run_server()
assert mock_reactor.run.call_count == 1
val_f = -3.33
builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big)
builder.add_32bit_float(val_f)
print(builder.to_registers()) # [49237, 7864]
client = ModbusSerialClient(method='rtu', baudrate=test_server_baudrate, timeout = test_server_timeout, port=os.ttyname(m))
client.connect()
assert client.is_socket_open() == True
client.write_registers(ModbusRTUServer.P_target_address, builder.to_registers())
assert server.get_P_target_float32() >= val_f - 0.01
assert server.get_P_target_float32() <= val_f + 0.01
这些是我最终得到的日志消息:
> assert server.get_P_target_float32() <= val_f + 0.01
E assert 4.775518667735688e-39 <= (-3.33 + 0.01)
E + where 4.775518667735688e-39 = <bound method ModbusRTUServer.get_P_target_float32 of <smc.ModbusRTUServer object at 0x7f2353f78d60>>()
E + where <bound method ModbusRTUServer.get_P_target_float32 of <smc.ModbusRTUServer object at 0x7f2353f78d60>> = <smc.ModbusRTUServer object at 0x7f2353f78d60>.get_P_target_float32
tests/test_modbus.py:47: AssertionError
-------------------------------------------------------------------------------------------------------- Captured log call --------------------------------------------------------------------------------------------------------
INFO pymodbus.server.asynchronous:asynchronous.py:327 Starting Modbus Serial Server on /dev/pts/12
DEBUG pymodbus.server.asynchronous:asynchronous.py:223 Running in spawned thread
DEBUG pymodbus.payload:payload.py:125 [49237, 7864]
DEBUG pymodbus.payload:payload.py:125 [49237, 7864]
DEBUG pymodbus.transaction:transaction.py:139 Current transaction state - IDLE
DEBUG pymodbus.transaction:transaction.py:144 Running transaction 1
DEBUG pymodbus.transaction:transaction.py:273 SEND: 0x0 0x10 0x0 0x33 0x0 0x2 0x4 0xc0 0x55 0x1e 0xb8 0x91 0x90
DEBUG pymodbus.client.sync:sync.py:76 New Transaction state 'SENDING'
DEBUG pymodbus.transaction:transaction.py:287 Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG pymodbus.transaction:transaction.py:303 Transaction failed. (Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received))
DEBUG pymodbus.framer.rtu_framer:rtu_framer.py:240 Frame - [b''] not ready
DEBUG pymodbus.transaction:transaction.py:465 Getting transaction 0
DEBUG pymodbus.transaction:transaction.py:224 Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
DEBUG pymodbus.payload:payload.py:312 [52, 52]
DEBUG pymodbus.payload:payload.py:368 [b'\x004', b'\x004']
DEBUG pymodbus.payload:payload.py:312 [52, 52]
DEBUG pymodbus.payload:payload.py:368 [b'\x004', b'\x004']
当我在连接到另一个 raspi 的真实串行端口上运行此服务器并在那里启动相同的客户端示例时,一切正常。
我在所有示例和测试中进行了搜索,但没有找到解决此问题的方法或如何通过真实串行端口进行此类测试的示例。非常感谢任何帮助!
解决方案
推荐阅读
- python-3.x - 为什么这个 n 选择 r python 代码不起作用?
- python - 对数据框中的值进行排序
- c++ - 临时实现转换不在标准转换顺序中
- javascript - 我可以在nodejs中的javascript中的路由中传递一个变量吗?我正在使用查询方法
- python - 使用 Python File IO 在 HTML 文件的特定位置添加文本
- javascript - 如何从全日历上的选择列表中为选定用户呈现事件
- php - Elastic Beanstalk、Circle CI 和 Laravel 自动部署
- r - 在 R 中加载包的字符串列表的优雅方式
- javascript - SocketCluster 客户端——TypeError:WebSocket 不是构造函数
- r - 如何在 R 中实现 SAS 百分位语句?