В чем причина получения результата для второй попытки чтения ModbusTcp? - PullRequest
0 голосов
/ 20 ноября 2018

Иногда я получаю ответ об ошибке сразу же при первом чтении с устройства Modbus, но при повторной попытке это дает ожидаемый результат.

Это сообщение об ошибке в первый раз:

pymodbus.exceptions.ModbusIOException(pymodbus.exceptions.InvalidMessageReceivedException('Incomplete message received, expected at least 8 bytes (0 received)'), 3)

Вот упрощенный фрагмент кода в консоли iPython:

In [1]: from pymodbus.client.sync import ModbusTcpClient
In [2]: cli = ModbusTcpClient('192.168.1.152', port=502)
In [3]: cli.connect()
Out[3]: True
In [4]: req = cli.read_holding_registers(0x1e, 2, unit=21)  # First try.
In [5]: req.isError()
Out[5]: True
In [6]: req
Out[6]: pymodbus.exceptions.ModbusIOException(pymodbus.exceptions.InvalidMessageReceivedException('Incomplete message received, expected at least 8 bytes (0 received)'), 3)
In [7]: req = cli.read_holding_registers(0x1e, 2, unit=21)  # Second try.
In [8]: req.isError()
Out[8]: False
In [9]: req.registers  # As expected.
Out[9]: [16091, 15697]

В чем причина?


[ОБНОВЛЕНИЕ]:

Я активирую ведение журнала ведомого / сервера Modbus:

import logging
from pymodbus.client.sync import ModbusTcpClient as ModbusClient

logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

client = ModbusClient('192.168.1.152', port=502)
client.connect() 

print('First Try: ')
res = client.read_holding_registers(0x1e, 2, unit=21)
print('isError = {}'.format(res.isError()))

print('Second Try: ')
res = client.read_holding_registers(0x1e, 2, unit=21)
print('isError = {}'.format(res.isError()))

client.close() 

Out:

First Try: 
DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x15 0x3 0x0 0x1e 0x0 0x2
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 8 bytes (0 received)) 
DEBUG:pymodbus.framer.socket_framer:Processing: 
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
isError = True
Second Try: 
DEBUG:pymodbus.transaction:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.transaction:Running transaction 2
DEBUG:pymodbus.transaction:SEND: 0x0 0x2 0x0 0x0 0x0 0x6 0x15 0x3 0x0 0x1e 0x0 0x2
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x0 0x2 0x0 0x0 0x0 0x7 0x15 0x3 0x4 0x3f 0x99 0x8 0xe8
DEBUG:pymodbus.framer.socket_framer:Processing: 0x0 0x2 0x0 0x0 0x0 0x7 0x15 0x3 0x4 0x3f 0x99 0x8 0xe8
DEBUG:pymodbus.factory:Factory Response[ReadHoldingRegistersResponse: 3]
DEBUG:pymodbus.transaction:Adding transaction 2
DEBUG:pymodbus.transaction:Getting transaction 2
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
isError = False

Как вы видите, в первой попытке я получил ошибку, но во второй попыткеЯ получил хороший результат.

1 Ответ

0 голосов
/ 29 ноября 2018

У меня была такая же проблема с контроллером теплового насоса Keba.Как уже упоминалось, моя проблема была решена путем увеличения времени ожидания до 10 секунд, в вашем примере

client = ModbusClient ('192.168.1.152', port = 502, timeout = 10)

10 секунд имели для меня некоторый запас, я наблюдал в Wireshark всегда около 5 секунд.Начиная со второго запроса, ответы всегда легко приходят за доли секунды.

Причина, по которой мой поставщик тепловых насосов был вызван тем, что у контроллера недостаточно памяти, а сервер Modbus запускается только при первом входящем запроседля подключения.

@ разработчики pymodbus: я предлагаю увеличить значение Default.timeout до 10 секунд.

...