Repository: pymodbus-dev/pymodbus

Issue:
Decoding Holding Registers to 16bit binary format 
### Versions

* Python: 3.9.13
* OS: Ubuntu 22.04
* Pymodbus: 2.5.3
* Modbus Hardware (if used): 

### Pymodbus Specific
* Server: tcp
* Client: tcp

### Description

In reference to the issue #634 

I am simulating a real case in which in a modbus server I have to read a holding register in binary format.

Reading the register and using the decode_bits() function I expect to receive a list of 16 bits.
decode_bits() only converts 1 byte.

### Code and Logs

```python
# register: 1101000000000000
result = self.connection.read_holding_registers(register, 1, unit=self.slave_unit)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, Endian.Big, wordorder=Endian.Little)
print(decoder.decode_bits())
# Result: [False, False, False, False, True, False, True, True]
# Expected: [False, False, False, False, False, False, False, False, False, False, False, False, True, False, True, True]

```



Discussion:
A holding register contains bytes (2 pr register) and not bits. Normally you interpret a holding register as an int.

You should be able to use result.registers directly, of course unless you want to do some special conversions.
> A holding register contains bytes (2 pr register) and not bits. Normally you interpret a holding register as an int.
> 
> You should be able to use result.registers directly, of course unless you want to do some special conversions.

Yes, I know this is not standard, but for what reason does decode_bits() only have to convert one byte?
Because that is how it is programmed 😃 

consider using e.g. decoder.decode_16bit_uint(), or make 2 calls to BinaryPayloadDecoder / decoder.decode_bits.



> Because that is how it is programmed smiley
> 
> consider using e.g. decoder.decode_16bit_uint(), or make 2 calls to BinaryPayloadDecoder / decoder.decode_bits.

Mine was not meant to be a provocation!
I expected to receive 2 bytes :)

Thank you
I did not take it as a provocation, hence my smiley.

I suspect it is code that was not touched since the beginning of time....please keep the issue open, and I will see if I can get it fixed, but I cannot promise you a timeline since I am pretty busy with a major rewrite of the whole client structure.

Ps. if/when I fix it, it will be on dev and not on 2.5.3.
AFAIK, `decode_bits` is historically used dealing with single byte registers and does not support multiple bytes.  It should be trivial to patch it support multiple bytes but not a hight priority task IMHO. PR's are welcome

Resolving patch:
diff --git a/pymodbus/payload.py b/pymodbus/payload.py
--- a/pymodbus/payload.py
+++ b/pymodbus/payload.py
@@ -373,9 +373,9 @@ def decode_8bit_uint(self):
         handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
-    def decode_bits(self):
+    def decode_bits(self, package_len=1):
         """Decode a byte worth of bits from the buffer."""
-        self._pointer += 1
+        self._pointer += package_len
         # fstring = self._endian + "B"
         handle = self._payload[self._pointer - 1 : self._pointer]
         handle = make_byte_string(handle)


Test patch: