# Buggy code
def fromRegisters(klass, registers, endian=Endian.Little):
    """Initialize a payload decoder with the result of
    reading a collection of registers from a modbus device.

    The registers are treated as a list of 2 byte values.
    We have to do this because of how the data has already
    been decoded by the rest of the library.

    :param registers: The register results to initialize with
    :param endian: The endianess of the payload
    :returns: An initialized PayloadDecoder
    """
    if isinstance(registers, list):  # repack into flat binary
        payload = b"".join(pack(endian + "H", x) for x in registers)
        return klass(payload, endian)
    raise ParameterException("Invalid collection of registers supplied")


# Traceback (AssertionError)
from pymodbus.client.sync import ModbusTcpClient as Client

import logging
# import time
import struct
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

write_value = 23
builder = BinaryPayloadBuilder(endian=Endian.Little)
builder.add_16bit_uint(write_value)
payload = builder.build()

#
count = 1
#
#
# c = Client(method="rtu", port="/tmp/ttyp0", timeout=2)
c = Client(port=5440)
c.connect()
#
r = c.write_registers(0, payload, skip_encode=True, unit=1)
r = c.read_holding_registers(0, 1, unit=1, skip_encode=True)
decoder = BinaryPayloadDecoder.fromRegisters(r.registers, endian=Endian.Little)
read_value = decoder.decode_16bit_uint()
log.debug("Wrote - {} , Read - {}".format(write_value, read_value))
assert read_value == write_value
c.close()

### Logs

DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:send: 0x0 0x1 0x0 0x0 0x0 0x9 0x1 0x10 0x0 0x0 0x0 0x1 0x2 0x17 0x0
DEBUG:pymodbus.transaction:recv: 0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x10 0x0 0x0 0x0 0x1
DEBUG:pymodbus.transaction:0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x10 0x0 0x0 0x0 0x1
DEBUG:pymodbus.factory:Factory Response[16]
DEBUG:pymodbus.transaction:adding transaction 1
DEBUG:pymodbus.transaction:getting transaction 1
DEBUG:pymodbus.transaction:Running transaction 2
DEBUG:pymodbus.transaction:send: 0x0 0x2 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x0 0x0 0x1
DEBUG:pymodbus.transaction:recv: 0x0 0x2 0x0 0x0 0x0 0x5 0x1 0x3 0x2 0x17 0x0
DEBUG:pymodbus.transaction:0x0 0x2 0x0 0x0 0x0 0x5 0x1 0x3 0x2 0x17 0x0
DEBUG:pymodbus.factory:Factory Response[3]
DEBUG:pymodbus.transaction:adding transaction 2
DEBUG:pymodbus.transaction:getting transaction 2
DEBUG:root:Wrote - 23 , Read - 5888
Traceback (most recent call last):
File "/Users/sanjay/Library/Preferences/PyCharm2017.3/scratches/scratch_49.py", line 31, in <module>
assert read_value == write_value
AssertionError

# Fixed code
def fromRegisters(klass, registers, endian=Endian.Little):
    """Initialize a payload decoder with the result of
    reading a collection of registers from a modbus device.

    The registers are treated as a list of 2 byte values.
    We have to do this because of how the data has already
    been decoded by the rest of the library.

    :param registers: The register results to initialize with
    :param endian: The endianess of the payload
    :returns: An initialized PayloadDecoder
    """
    if isinstance(registers, list):  # repack into flat binary
        payload = b"".join(pack("!H", x) for x in registers)
        return klass(payload, endian)
    raise ParameterException("Invalid collection of registers supplied")