pymodbus-dev/pymodbus

Data loss, but can't find the error

Closed this issue · 13 comments

Versions

  • Python: 3.12.4
  • OS: Win11
  • Pymodbus: 3.7.0

Pymodbus Specific

  • Client: rtu - sync

Description

I tried to read data from the Modbus slave, which should return voltage values, e.g.:
Tue Nov 5 10:08:19 2024 - S1: [1.00V/0.90V], (loop duration: 0.992s)

However, I irregular receive errors like this:
Tue Nov 5 10:08:20 2024 - Pressure @ Address 1 - ModbusIOException: <class 'AttributeError'>
Tue Nov 5 10:08:21 2024 - S1: [0.00V/0.00V], (loop duration: 1.113s)

The log shows: .
(DEBUG:pymodbus.logging:Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 4 bytes (3 received)))

I checked with other programs, and there is no data loss.
I assume there is an error in my code, but I can't find it.

Thanks.

Code and Logs

from pymodbus.client import ModbusSerialClient
from pymodbus.exceptions import ModbusIOException
import time
import argparse
import logging

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

# Argument Parser
parser = argparse.ArgumentParser(prog=None,
                                     usage=None,
                                     description="Enter Port, Baudrate, Addres and Slave_ID")
parser.add_argument('port', type=str, help="Set the port of the USB serial port ")
parser.add_argument('baudrate', type=int, help="Set the baudrate")
parser.add_argument('address', type=int, help="Set the address/register  of the modbus")
parser.add_argument('slave_id', type=int, help="Set the slave ID")
# parser.add_argument('coils', type=int, help="Set the number of coils")
args = parser.parse_args()

# args.port ='COM5'
# args.baudrate = 38400
# args.address = 0
# args.coils = 2
# args.slave_id = 1

#Change unsigned to signed16bit:
def to_signed_16bit(value):
    if value > 32767:
        return value - 65536
    else:
        return value

# pymodbus
MODBUS_PORT = args.port 
MODBUS_BAUDRATE = args.baudrate   # 115k2
address_mod = args.address
nbr_coils = 2
slave_id = args.slave_id

# outout file
FILE_NAME = time.strftime('%Y%m%d_%H-%M_pressuretrace.txt')


def read_pressure_values(client: ModbusSerialClient, slave_id):
    temp_1 = 0.0
    temp_2 = 0.0


    try:
        msg = client.read_input_registers(address=address_mod,count=nbr_coils,slave=slave_id)
        var_1 = to_signed_16bit(msg.registers[0])
        var_2 = to_signed_16bit(msg.registers[1])
        temp_1 = (var_1 +30000)/50000
        temp_2 =(var_2 +30000)/50000


    except AttributeError:
        print(f"{time.ctime()} - Pressure @ Address {slave_id} - ModbusIOException: {AttributeError}")
    
    # except AttributeError as exc:
    #     txt = f"ERROR: exception in pymodbus {exc}"
    #     log.error(txt)
    #     return None, None, None
    # if msg.isError():
    #     txt = "ERROR: pymodbus returned an error!"
    #     log.error(txt)

    return temp_1, temp_2


if __name__ == '__main__':
    # access modbus
    client = ModbusSerialClient(port=MODBUS_PORT,baudrate=MODBUS_BAUDRATE,timeout=1)
    
    if not client.connect():
        print("Connection to Modbus-Slave failed")
        exit()
	
	# measurement loop
    try:
        with open(FILE_NAME, 'w') as f:
            # write talbe header
            f.write("time\t")
            f.write("voltage_1\tvoltgae_2\t")
            f.write("\n")

            # measurement loop
            while True: 
                start_time = time.time()

                # read modbus msf sensor at address 1
                s1_values = read_pressure_values(client, slave_id)

                # sleep
                time.sleep(0.98)

                # write measurement data to file
                f.write(f"{time.time()}\t") # timestamp
                # data from sensor at address 1
                f.write("{:.2f}\t{:.2f}\t".format(  
                    s1_values[0],
                    s1_values[1]
                ))
                                
                f.write("\n")   # line break
                
                # measure loop duration
                loop_duration = time.time() - start_time
                

                # write debug data to terminal
                print(f"{time.ctime()} - ", end='')
                print("S1: [{:.2f}V/{:.2f}V], ".format(
                    s1_values[0],
                    s1_values[1]
                ), end='')
                
                print(f"  (loop duration: {loop_duration:.3f}s)")

    # break loop and close application with keyboard shortcut [Ctrl+C]
    except KeyboardInterrupt:
        print("Measurement stopped!")

Log:

DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.logging:Running transaction 40
DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb
DEBUG:pymodbus.logging:Resetting frame - Current Frame in buffer -
DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - 1730797962.28427 Current Time stamp - 1730797963.268734
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2b 0x4e 0x64
DEBUG:pymodbus.logging:Processing: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2b 0x4e 0x64
DEBUG:pymodbus.logging:Getting Frame - 0x4 0x4 0x4d 0xf3 0x3a 0x2b
DEBUG:pymodbus.logging:Factory Response[ReadInputRegistersResponse': 4]
DEBUG:pymodbus.logging:Frame advanced, resetting header!!
DEBUG:pymodbus.logging:Adding transaction 0
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Tue Nov  5 10:12:44 2024 - S1: [1.00V/0.90V],   (loop duration: 1.008s)
DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.logging:Running transaction 41
DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb
DEBUG:pymodbus.logging:Resetting frame - Current Frame in buffer -
DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - 1730797963.291558 Current Time stamp - 1730797964.274867
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 4 bytes (3 received))
DEBUG:pymodbus.logging:Processing:
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Tue Nov  5 10:12:44 2024 - Pressure @ Address 1 - ModbusIOException: <class 'AttributeError'>
Tue Nov  5 10:12:45 2024 - S1: [0.00V/0.00V],   (loop duration: 1.121s)
DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.logging:Running transaction 42
DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb
DEBUG:pymodbus.logging:Resetting frame - Current Frame in buffer -
DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - None Current Time stamp - 1730797965.416676
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x1 0x4 0x4 0x4d 0xf2 0x3a 0x2b 0x1f 0xa4
DEBUG:pymodbus.logging:Got response!!!
DEBUG:pymodbus.logging:Processing: 0x1 0x4 0x4 0x4d 0xf2 0x3a 0x2b 0x1f 0xa4
DEBUG:pymodbus.logging:Getting Frame - 0x4 0x4 0x4d 0xf2 0x3a 0x2b
DEBUG:pymodbus.logging:Factory Response[ReadInputRegistersResponse': 4]
DEBUG:pymodbus.logging:Frame advanced, resetting header!!
DEBUG:pymodbus.logging:Adding transaction 0
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Tue Nov  5 10:12:46 2024 - S1: [1.00V/0.90V],   (loop duration: 1.021s)
DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.logging:Running transaction 43
DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb
DEBUG:pymodbus.logging:Resetting frame - Current Frame in buffer -
DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - 1730797965.43148 Current Time stamp - 1730797966.417118
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2b 0x4e 0x64
DEBUG:pymodbus.logging:Processing: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2b 0x4e 0x64
DEBUG:pymodbus.logging:Getting Frame - 0x4 0x4 0x4d 0xf3 0x3a 0x2b
DEBUG:pymodbus.logging:Factory Response[ReadInputRegistersResponse': 4]
DEBUG:pymodbus.logging:Frame advanced, resetting header!!
DEBUG:pymodbus.logging:Adding transaction 0
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"

Please add a debug (add the issue template explained), otherwise we cannot see what is going on.

Seems like your device sometimes do not respond, but the log will tell.

You should really upgrade to current version 3.7.4 as many bugs have been solved.

Your except is wrong, you log the class, not the object, so it is impossible to see which attribute is causing a problem.

The log shows your device not respond, maybe your timeout is too short.

Sorry for the late response!
At first, I also thought my timeout was too short, but this didn’t solve the problem.

The log shows your device not respond, maybe your timeout is too short.

I updated my pymodbus to 3.7.4, and this solved the problem a litte bit. The error occurs less frequently.

Please add a debug (add the issue template explained), otherwise we cannot see what is going on.

Seems like your device sometimes do not respond, but the log will tell.

You should really upgrade to current version 3.7.4 as many bugs have been solved.

The log shows your device not respond, maybe your timeout is too short.

I chaned the except to:

except AttributeError as exc: print(f"{time.ctime()} - Pressure @ Address {slave_id} - ModbusIOException: {exc}")

And the log shows:

``
DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.logging:Running transaction 0
DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb
DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - 1730875183.877877 Current Time stamp - 1730875184.861225
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66
DEBUG:pymodbus.logging:Processing: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66
DEBUG:pymodbus.logging:decode PDU for 4
DEBUG:pymodbus.logging:Frame advanced, resetting header!!
DEBUG:pymodbus.logging:Adding transaction 0
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Wed Nov 6 07:39:45 2024 - S1: [1.00V/0.90V], (loop duration: 1.007s)

DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.logging:Running transaction 0
DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb
DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - 1730875184.882941 Current Time stamp - 1730875185.869199
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6
DEBUG:pymodbus.logging:Processing: 0x1 0x4 0x4 0x4d 0xf3 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6
DEBUG:pymodbus.logging:Frame check failed, ignoring!!
DEBUG:pymodbus.logging:Frame - not ready
DEBUG:pymodbus.logging:Processing: 0x4 0x4 0x4d 0xf3 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6
DEBUG:pymodbus.logging:Frame - not ready
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Wed Nov 6 07:39:46 2024 - Pressure @ Address 1 - ModbusIOException: 'ModbusIOException' object has no attribute 'registers'
Wed Nov 6 07:39:46 2024 - S1: [0.00V/0.00V], (loop duration: 1.127s)

DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.logging:Running transaction 0
DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb
DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - None Current Time stamp - 1730875187.017396
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6
DEBUG:pymodbus.logging:Processing: 0x4 0x4 0x4d 0xf3 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6
DEBUG:pymodbus.logging:Frame - not ready
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Wed Nov 6 07:39:47 2024 - Pressure @ Address 1 - ModbusIOException: 'ModbusIOException' object has no attribute 'registers'
Wed Nov 6 07:39:48 2024 - S1: [0.00V/0.00V], (loop duration: 1.270s)

DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.logging:Running transaction 0
DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb
DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - None Current Time stamp - 1730875188.288623
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6
DEBUG:pymodbus.logging:Processing: 0x4 0x4 0x4d 0xf3 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6
DEBUG:pymodbus.logging:Frame - not ready
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Wed Nov 6 07:39:48 2024 - Pressure @ Address 1 - ModbusIOException: 'ModbusIOException' object has no attribute 'registers'
Wed Nov 6 07:39:49 2024 - S1: [0.00V/0.00V], (loop duration: 1.160s)

DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.logging:Running transaction 0
DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb
DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - None Current Time stamp - 1730875189.448481
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 4 bytes (2 received))
DEBUG:pymodbus.logging:Processing: 0x4 0x4 0x4d 0xf3 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2d 0xce 0x66 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2c 0xf 0xa6
DEBUG:pymodbus.logging:Frame - not ready
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Wed Nov 6 07:39:49 2024 - Pressure @ Address 1 - ModbusIOException: 'ModbusIOException' object has no attribute 'registers'
Wed Nov 6 07:39:50 2024 - S1: [0.00V/0.00V], (loop duration: 1.142s)
``

The attribute error is a bug, which I will take a look at, but the base problem is the same, your device sometimes do not respond, and the app gets a ModbusIOException, which is needs to handle, e,g, by using isError()

The attribute error is a bug, which I will take a look at, but the base problem is the same, your device sometimes do not respond, and the app gets a ModbusIOException, which is needs to handle, e,g, by using isError()

Like this:

except AttributeError as exc: txt = f"ERROR: exception in pymodbus {exc}" log.error(txt) return None, None, None if msg.isError(): txt = "ERROR: pymodbus returned an error!" log.error(txt)

The log is:

DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE DEBUG:pymodbus.logging:Running transaction 0 DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - 1730893305.984209 Current Time stamp - 1730893306.789979 DEBUG:pymodbus.logging:New Transaction state "SENDING" DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY" DEBUG:pymodbus.logging:Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 4 bytes (3 received)) DEBUG:pymodbus.logging:Processing: DEBUG:pymodbus.logging:Getting transaction 0 DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE" ERROR:root:ERROR: exception in pymodbus 'ModbusIOException' object has no attribute 'registers' Traceback (most recent call last): File "\pressure_reader.py", line 103, in <module> f.write("{:.2f}\t{:.2f}\t".format( ^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: unsupported format string passed to NoneType.__format__

I figured out that it's not the timeout=1 that solves the problem, but increasing time.sleep(0.9) from 0.9 to 1.1.
This solves the issue, and I'm no longer experiencing any data loss!

It's neither my hardware nor my code that causes the data loss.
I checked it with another program and reduced the replay time to about 23ms.
Could it be the library that's limiting the refresh rate?

image

neither v3.7.4 nor dev have a line with "time.sleep(0.9)", so I am not sure what you refer to...the library do have restraints, but there are all within an API call, between API calls there are nothing going on in the library.

The library do no limit the refresh rate ! it does what the app tells it to.

If a sleep(1.1) between API calls work but sleep(0.9) do not, then please make 1 (or 2) debug logs showing 1.1 and 0.9, so we can see the exact difference.

Sorry, I meant in my script:

`

            s1_values = read_pressure_values(client, slave_id)

            # sleep
            time.sleep(0.98)

            # write measurement data to file
            f.write(f"{time.time()}\t") # timestamp
            # data from sensor at address 1
            f.write("{:.2f}\t{:.2f}\t".format(  
                s1_values[0],
                s1_values[1]

`

But that is as I wrote in-between API calls, and the library does nothing in that time, especially the sync client. So if 1.1 second is needed it sounds more like a device issue.

But as I also wrote provide a debug log with 1.1 and 0.9, then we can see if the library does something different or it is external to the library.

I don’t think it’s my device, as I shared a picture from another program showing the device request and response time of 23 ms.

Here is the log of time.sleep(0.8):

DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE DEBUG:pymodbus.logging:Running transaction 0 DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - 1730960483.014588 Current Time stamp - 1730960483.821095 DEBUG:pymodbus.logging:New Transaction state "SENDING" DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY" DEBUG:pymodbus.logging:Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 4 bytes (2 received)) DEBUG:pymodbus.logging:Processing: DEBUG:pymodbus.logging:Getting transaction 0 DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE" ERROR:root:ERROR: exception in pymodbus 'ModbusIOException' object has no attribute 'registers' Traceback (most recent call last): File "\pressure_reader.py", line 103, in <module> f.write("{:.2f}\t{:.2f}\t".format( ^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: unsupported format string passed to NoneType.__format__

And here is the log from time.sleep(1.1.), where no error occurs. I terminated it after a couple of minutes:

Thu Nov 7 07:28:48 2024 - S1: [1.00V/0.90V], (loop duration: 1.120s) DEBUG:pymodbus.logging:Current transaction state - TRANSACTION_COMPLETE DEBUG:pymodbus.logging:Running transaction 0 DEBUG:pymodbus.logging:SEND: 0x1 0x4 0x0 0x0 0x0 0x2 0x71 0xcb DEBUG:pymodbus.logging:Changing state to IDLE - Last Frame End - 1730960927.003888 Current Time stamp - 1730960928.109038 DEBUG:pymodbus.logging:New Transaction state "SENDING" DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY" DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY" DEBUG:pymodbus.logging:RECV: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2a 0x8f 0xa4 DEBUG:pymodbus.logging:Processing: 0x1 0x4 0x4 0x4d 0xf3 0x3a 0x2a 0x8f 0xa4 DEBUG:pymodbus.logging:decode PDU for 4 DEBUG:pymodbus.logging:Frame advanced, resetting header!! DEBUG:pymodbus.logging:Adding transaction 0 DEBUG:pymodbus.logging:Getting transaction 0 DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE" Measurement stopped!

Log 1 and 2 are from different situations just look at the first log line!
(log 2 seems to be a second API call).

Seems to me you are suggesting that the response you receive in the API call is modified AFTER it is returned to the app, that is not possible.

We are currently working on 2 patches for the sync client, that affects how it reads data, however I do see your case different, since the sync version have no threads or anything else that runs between calls.

Btw in read pressure values you need to check isError(), otherwise you will get attributeErrors when a call fails.

Log 1 shows that the logging you do in the except is wrong.