Repository: pymodbus-dev/pymodbus

Issue:
Bug or misunderstanding of word_order in convert methods
Look at this code:

```python
from pymodbus.client.mixin import ModbusClientMixin


original_values = [1.0, 2.0, 3.0]
registers = ModbusClientMixin.convert_to_registers(
    original_values, ModbusClientMixin.DATATYPE.FLOAT32, word_order="little"
)

converted_values = ModbusClientMixin.convert_from_registers(
    registers, ModbusClientMixin.DATATYPE.FLOAT32, word_order="little"
)
print("Original values:", original_values)
print("Converted registers:", registers)
print("Converted back values:", converted_values)
```

I expected this result:

```
Original values: [1.0, 2.0, 3.0]
Converted registers: [0, 16448, 0, 16384, 0, 16256]
Converted back values: [1.0, 2.0, 3.0]
```

But got:

```
Original values: [1.0, 2.0, 3.0]
Converted registers: [0, 16448, 0, 16384, 0, 16256]
Converted back values: [3.0, 2.0, 1.0]
```

I thought the "word_order" was meant to be used in order to specify how words are ordered when decomposing datatypes with more bytes. For example in a 4 byte float that will be transmited as 2 words I expected "word_order" to determine if the first word has the least significant portion (little) or the most significant part (big).

But checking at the code I can see all it does is reverse all the registers or something like that. 

I guess I'm just misunderstanding something...





Discussion:
You do not write which version you are using ??

Apart from that, to_registers actually expect one value not multiple, in which case the regs.reverse() is correct.

It is correct that it could easily be changed to loop over multiple values, pull requests are welcome.



Patch:
diff --git a/pymodbus/client/mixin.py b/pymodbus/client/mixin.py
index 3976597df..1af3aa9c5 100644
--- a/pymodbus/client/mixin.py
+++ b/pymodbus/client/mixin.py
@@ -771,5 +771,19 @@ def convert_to_registers(
             for x in range(0, len(byte_list), 2)
         ]
         if word_order == "little":
-            regs.reverse()
+            return cls._get_reversed_registers(regs, data_type)
+
         return regs
+
+    @classmethod
+    def _get_reversed_registers(cls, regs: list[int], data_type: DATATYPE) -> list[int]:
+        if not (data_type_len := data_type.value[1]):
+            regs.reverse()
+            return regs
+
+        reversed_regs: list[int] = []
+        for x in range(0, len(regs), data_type_len):
+            single_value_regs = regs[x: x + data_type_len]
+            single_value_regs.reverse()
+            reversed_regs = reversed_regs + single_value_regs
+        return reversed_regs


Test patch:
diff --git a/test/client/test_client.py b/test/client/test_client.py
index 84b942e8b..bad622a7a 100755
--- a/test/client/test_client.py
+++ b/test/client/test_client.py
@@ -105,9 +105,22 @@ def fake_execute(_self, _no_response_expected, request):
             (ModbusClientMixin.DATATYPE.STRING, "a", [0x6100], None),
             (ModbusClientMixin.DATATYPE.UINT16, 27123, [0x69F3], None),
             (ModbusClientMixin.DATATYPE.INT16, -27123, [0x960D], None),
+            (ModbusClientMixin.DATATYPE.INT16, [-27123, 27123], [0x960D, 0x69F3], None),
             (ModbusClientMixin.DATATYPE.UINT32, 27123, [0x0000, 0x69F3], None),
             (ModbusClientMixin.DATATYPE.UINT32, 32145678, [0x01EA, 0x810E], None),
+            (
+                ModbusClientMixin.DATATYPE.UINT32,
+                [27123, 32145678],
+                [0x0000, 0x69F3, 0x01EA, 0x810E],
+                None
+            ),
             (ModbusClientMixin.DATATYPE.INT32, -32145678, [0xFE15, 0x7EF2], None),
+            (
+                ModbusClientMixin.DATATYPE.INT32,
+                [32145678, -32145678],
+                [0x01EA, 0x810E, 0xFE15, 0x7EF2],
+                None
+            ),
             (
                 ModbusClientMixin.DATATYPE.UINT64,
                 1234567890123456789,
@@ -120,9 +133,21 @@ def fake_execute(_self, _no_response_expected, request):
                 [0xEEDD, 0xEF0B, 0x8216, 0x7EEB],
                 None,
             ),
+            (
+                ModbusClientMixin.DATATYPE.INT64,
+                [1234567890123456789, -1234567890123456789],
+                [0x1122, 0x10F4, 0x7DE9, 0x8115, 0xEEDD, 0xEF0B, 0x8216, 0x7EEB],
+                None,
+            ),
             (ModbusClientMixin.DATATYPE.FLOAT32, 27123.5, [0x46D3, 0xE700], None),
             (ModbusClientMixin.DATATYPE.FLOAT32, 3.141592, [0x4049, 0x0FD8], None),
             (ModbusClientMixin.DATATYPE.FLOAT32, -3.141592, [0xC049, 0x0FD8], None),
+            (
+                ModbusClientMixin.DATATYPE.FLOAT32,
+                [27123.5, 3.141592, -3.141592],
+                [0x46D3, 0xE700, 0x4049, 0x0FD8, 0xC049, 0x0FD8],
+                None
+            ),
             (ModbusClientMixin.DATATYPE.FLOAT64, 27123.5, [0x40DA, 0x7CE0, 0x0000, 0x0000], None),
             (
                 ModbusClientMixin.DATATYPE.FLOAT64,
@@ -136,6 +161,12 @@ def fake_execute(_self, _no_response_expected, request):
                 [0xC009, 0x21FB, 0x5444, 0x2D11],
                 None,
             ),
+            (
+                ModbusClientMixin.DATATYPE.FLOAT64,
+                [3.14159265358979, -3.14159265358979],
+                [0x4009, 0x21FB, 0x5444, 0x2D11, 0xC009, 0x21FB, 0x5444, 0x2D11],
+                None,
+            ),
             (
                 ModbusClientMixin.DATATYPE.BITS,
                 [True],
@@ -195,7 +226,16 @@ def fake_execute(_self, _no_response_expected, request):
     def test_client_mixin_convert(self, datatype, word_order, registers, value, string_encoding):
         """Test converter methods."""
         if word_order == "little":
-            registers = list(reversed(registers))
+            if not (datatype_len := datatype.value[1]):
+                registers = list(reversed(registers))
+            else:
+                reversed_regs: list[int] = []
+                for x in range(0, len(registers), datatype_len):
+                    single_value_regs = registers[x: x + datatype_len]
+                    single_value_regs.reverse()
+                    reversed_regs = reversed_regs + single_value_regs
+                registers = reversed_regs
+
 
         kwargs = {**({"word_order": word_order} if word_order else {}),
                   **({"string_encoding": string_encoding} if string_encoding else {})}
@@ -207,7 +247,10 @@ def test_client_mixin_convert(self, datatype, word_order, registers, value, stri
             if (missing := len(value) % 16):
                 value = value + [False] * (16 - missing)
         if datatype == ModbusClientMixin.DATATYPE.FLOAT32:
-            result = round(result, 6)
+            if isinstance(result, list):
+                result = [round(v, 6) for v in result]
+            else:
+                result = round(result, 6)
         assert result == value
 
     @pytest.mark.parametrize(