Skip to content

decode coils return incorrect result #2146

Description

@skymylife902

for coils decoded data, this line of code will fetch the trailing items rather than the leading items. It results in wrong data.

I tried following code to verify the logic:

from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder

if __name__ == '__main__':
    objects_count = 2

    byte_order = Endian.LITTLE
    word_order = Endian.BIG

    # mock coils data
    encoded_data = [True, False, False, False, False, False, False, False]

    decoder = BinaryPayloadDecoder.fromCoils(encoded_data, byteorder=byte_order, _wordorder=word_order)
    decoded = decoder.decode_bits()
    decoded_lastbyte = decoder.decode_bits()
    decoded += decoded_lastbyte
    decoded = decoded[len(decoded) - objects_count:]
    print('result: ', decoded)  # it prints [False, True], not [True, False]

after investigating, this issue is caused by the reverse of bits in the BinaryPayloadDecoder.fromCoils().

Image

By design, the original bits in ReadCoilsResponse is in the same order as the actual coils. when creating decoder, the code is supposed to pack the bits to bytes in the reversed order and at last at decoding stage, read the bits back reversely again. so first right order(response bits) -> reverse order(decoder packing) -> reversed reverse order = right order(decode) will return correct result. However, in the BinaryPayloadDecoder.fromCoils() method, it reverses the original coils bits prior to packing it into bytes. So the processing sequence become: original bits(coils bits) -> reversed bits(from coils) -> reversed reversed bits = original bits(packing) -> reversed bits(decode). And then, the code fetches the bits from beginning, resulting incorrectly bit value:

    if lower_type in ['bit', 'bits']:
        decoded = decoder_functions[lower_type]()
        decoded_lastbyte = decoder_functions[lower_type]()
        decoded += decoded_lastbyte
        decoded = decoded[len(decoded)-objects_count:]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions