]> git.basschouten.com Git - openhab-addons.git/blob
8647903b24e63cebaad94d971711371b22e1adf2
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.io.transport.modbus.test;
14
15 import static org.hamcrest.CoreMatchers.*;
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.junit.jupiter.api.Assertions.assertThrows;
18
19 import java.nio.ByteBuffer;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Optional;
23 import java.util.stream.Collectors;
24 import java.util.stream.IntStream;
25 import java.util.stream.Stream;
26
27 import org.eclipse.jdt.annotation.NonNull;
28 import org.junit.jupiter.params.ParameterizedTest;
29 import org.junit.jupiter.params.provider.MethodSource;
30 import org.openhab.core.library.types.DecimalType;
31 import org.openhab.io.transport.modbus.ModbusBitUtilities;
32 import org.openhab.io.transport.modbus.ModbusConstants.ValueType;
33 import org.openhab.io.transport.modbus.ModbusRegister;
34 import org.openhab.io.transport.modbus.ModbusRegisterArray;
35
36 /**
37  * @author Sami Salonen - Initial contribution
38  */
39 public class BitUtilitiesExtractStateFromRegistersTest {
40
41     private static ModbusRegisterArray shortArrayToRegisterArray(int... arr) {
42         ModbusRegister[] tmp = new ModbusRegister[0];
43         return new ModbusRegisterArray(IntStream.of(arr).mapToObj(val -> {
44             ByteBuffer buffer = ByteBuffer.allocate(2);
45             buffer.putShort((short) val);
46             return new ModbusRegister(buffer.get(0), buffer.get(1));
47         }).collect(Collectors.toList()).toArray(tmp));
48     }
49
50     public static Collection<Object[]> data() {
51         return Collections.unmodifiableList(Stream.of(
52                 //
53                 // BIT
54                 //
55                 new Object[] { new DecimalType("1.0"), ValueType.BIT,
56                         shortArrayToRegisterArray(1 << 5 | 1 << 4 | 1 << 15), 4 },
57                 new Object[] { new DecimalType("1.0"), ValueType.BIT,
58                         shortArrayToRegisterArray(1 << 5 | 1 << 4 | 1 << 15), 15 },
59                 new Object[] { new DecimalType("0.0"), ValueType.BIT, shortArrayToRegisterArray(1 << 5), 7 },
60                 new Object[] { new DecimalType("1.0"), ValueType.BIT, shortArrayToRegisterArray(1 << 5), 5 },
61                 new Object[] { new DecimalType("0.0"), ValueType.BIT, shortArrayToRegisterArray(1 << 5), 4 },
62                 new Object[] { new DecimalType("0.0"), ValueType.BIT, shortArrayToRegisterArray(1 << 5), 0 },
63                 new Object[] { new DecimalType("0.0"), ValueType.BIT, shortArrayToRegisterArray(0, 0), 15 },
64                 new Object[] { new DecimalType("1.0"), ValueType.BIT, shortArrayToRegisterArray(1 << 5, 1 << 4), 5 },
65                 new Object[] { new DecimalType("1.0"), ValueType.BIT, shortArrayToRegisterArray(1 << 5, 1 << 4), 20 },
66                 new Object[] { IllegalArgumentException.class, ValueType.BIT, shortArrayToRegisterArray(1 << 5), 16 },
67                 new Object[] { IllegalArgumentException.class, ValueType.BIT, shortArrayToRegisterArray(1 << 5), 200 },
68                 new Object[] { IllegalArgumentException.class, ValueType.BIT, shortArrayToRegisterArray(), 0 },
69                 new Object[] { IllegalArgumentException.class, ValueType.BIT, shortArrayToRegisterArray(0, 0), 32 },
70                 //
71                 // INT8
72                 //
73                 new Object[] { new DecimalType("5.0"), ValueType.INT8, shortArrayToRegisterArray(5), 0 },
74                 new Object[] { new DecimalType("-5.0"), ValueType.INT8, shortArrayToRegisterArray(-5), 0 },
75                 new Object[] { new DecimalType("3.0"), ValueType.INT8,
76                         shortArrayToRegisterArray(((byte) 6 << 8) | (byte) 3), 0 },
77                 new Object[] { new DecimalType("6.0"), ValueType.INT8,
78                         shortArrayToRegisterArray(((byte) 6 << 8) | (byte) 3), 1 },
79                 new Object[] { new DecimalType("4.0"), ValueType.INT8,
80                         shortArrayToRegisterArray(((byte) 6 << 8) | (byte) 3, 4), 2 },
81                 new Object[] { new DecimalType("6.0"), ValueType.INT8,
82                         shortArrayToRegisterArray(55, ((byte) 6 << 8) | (byte) 3), 3 },
83                 new Object[] { IllegalArgumentException.class, ValueType.INT8, shortArrayToRegisterArray(1), 2 },
84                 new Object[] { IllegalArgumentException.class, ValueType.INT8, shortArrayToRegisterArray(1, 2), 4 },
85                 //
86                 // UINT8
87                 //
88                 new Object[] { new DecimalType("5.0"), ValueType.UINT8, shortArrayToRegisterArray(5), 0 },
89                 new Object[] { new DecimalType("251.0"), ValueType.UINT8, shortArrayToRegisterArray(-5), 0 },
90                 new Object[] { new DecimalType("3.0"), ValueType.UINT8,
91                         shortArrayToRegisterArray(((byte) 6 << 8) | (byte) 3), 0 },
92                 new Object[] { new DecimalType("6.0"), ValueType.UINT8,
93                         shortArrayToRegisterArray(((byte) 6 << 8) | (byte) 3), 1 },
94                 new Object[] { new DecimalType("4.0"), ValueType.UINT8,
95                         shortArrayToRegisterArray(((byte) 6 << 8) | (byte) 3, 4), 2 },
96                 new Object[] { new DecimalType("6.0"), ValueType.UINT8,
97                         shortArrayToRegisterArray(55, ((byte) 6 << 8) | (byte) 3), 3 },
98                 new Object[] { IllegalArgumentException.class, ValueType.UINT8, shortArrayToRegisterArray(1), 2 },
99                 new Object[] { IllegalArgumentException.class, ValueType.UINT8, shortArrayToRegisterArray(1, 2), 4 },
100
101                 //
102                 // INT16
103                 //
104                 new Object[] { new DecimalType("1.0"), ValueType.INT16, shortArrayToRegisterArray(1), 0 },
105                 new Object[] { new DecimalType("2.0"), ValueType.INT16, shortArrayToRegisterArray(2), 0 },
106                 new Object[] { new DecimalType("-1004"), ValueType.INT16, shortArrayToRegisterArray(-1004), 0 },
107                 new Object[] { new DecimalType("-1536"), ValueType.INT16, shortArrayToRegisterArray(64000), 0 },
108                 new Object[] { new DecimalType("-1004"), ValueType.INT16, shortArrayToRegisterArray(4, -1004), 1 },
109                 new Object[] { new DecimalType("-1004"), ValueType.INT16, shortArrayToRegisterArray(-1004, 4), 0 },
110                 new Object[] { IllegalArgumentException.class, ValueType.INT16, shortArrayToRegisterArray(4, -1004),
111                         2 },
112                 //
113                 // UINT16
114                 //
115                 new Object[] { new DecimalType("1.0"), ValueType.UINT16, shortArrayToRegisterArray(1), 0 },
116                 new Object[] { new DecimalType("2.0"), ValueType.UINT16, shortArrayToRegisterArray(2), 0 },
117                 new Object[] { new DecimalType("64532"), ValueType.UINT16, shortArrayToRegisterArray(-1004), 0 },
118                 new Object[] { new DecimalType("64000"), ValueType.UINT16, shortArrayToRegisterArray(64000), 0 },
119                 new Object[] { new DecimalType("64532"), ValueType.UINT16, shortArrayToRegisterArray(4, -1004), 1 },
120                 new Object[] { new DecimalType("64532"), ValueType.UINT16, shortArrayToRegisterArray(-1004, 4), 0 },
121                 new Object[] { IllegalArgumentException.class, ValueType.INT16, shortArrayToRegisterArray(4, -1004),
122                         2 },
123                 //
124                 // INT32
125                 //
126                 new Object[] { new DecimalType("1.0"), ValueType.INT32, shortArrayToRegisterArray(0, 1), 0 },
127                 new Object[] { new DecimalType("2.0"), ValueType.INT32, shortArrayToRegisterArray(0, 2), 0 },
128                 new Object[] { new DecimalType("-1004"), ValueType.INT32,
129                         // -1004 = 0xFFFFFC14 (32bit) =
130                         shortArrayToRegisterArray(0xFFFF, 0xFC14), 0 },
131                 new Object[] { new DecimalType("64000"), ValueType.INT32, shortArrayToRegisterArray(0, 64000), 0 },
132                 new Object[] { new DecimalType("-1004"), ValueType.INT32,
133                         // -1004 = 0xFFFFFC14 (32bit) =
134                         shortArrayToRegisterArray(0x4, 0xFFFF, 0xFC14), 1 },
135                 new Object[] { new DecimalType("-1004"), ValueType.INT32,
136                         // -1004 = 0xFFFFFC14 (32bit) =
137                         shortArrayToRegisterArray(0xFFFF, 0xFC14, 0x4), 0 },
138                 new Object[] { IllegalArgumentException.class, ValueType.INT32, shortArrayToRegisterArray(4, -1004),
139                         1 },
140                 new Object[] { IllegalArgumentException.class, ValueType.INT32, shortArrayToRegisterArray(4, -1004),
141                         2 },
142                 new Object[] { IllegalArgumentException.class, ValueType.INT32, shortArrayToRegisterArray(0, 0, 0), 2 },
143                 //
144                 // UINT32
145                 //
146                 new Object[] { new DecimalType("1.0"), ValueType.UINT32, shortArrayToRegisterArray(0, 1), 0 },
147                 new Object[] { new DecimalType("2.0"), ValueType.UINT32, shortArrayToRegisterArray(0, 2), 0 },
148                 new Object[] { new DecimalType("4294966292"), ValueType.UINT32,
149                         // 4294966292 = 0xFFFFFC14 (32bit) =
150                         shortArrayToRegisterArray(0xFFFF, 0xFC14), 0 },
151                 new Object[] { new DecimalType("64000"), ValueType.UINT32, shortArrayToRegisterArray(0, 64000), 0 },
152                 new Object[] {
153                         // out of bounds of unsigned 16bit (0 to 65,535)
154                         new DecimalType("70004"),
155                         // 70004 -> 0x00011174 (32bit) -> 0x1174 (16bit)
156                         ValueType.UINT32, shortArrayToRegisterArray(1, 4468), 0 },
157                 new Object[] { new DecimalType("4294966292"), ValueType.UINT32,
158                         // 4294966292 = 0xFFFFFC14 (32bit) =
159                         shortArrayToRegisterArray(0xFFFF, 0xFC14, 0x5), 0 },
160                 new Object[] { new DecimalType("4294966292"), ValueType.UINT32,
161                         // 4294966292 = 0xFFFFFC14 (32bit) =
162                         shortArrayToRegisterArray(0x5, 0xFFFF, 0xFC14), 1 },
163                 new Object[] { IllegalArgumentException.class, ValueType.UINT32, shortArrayToRegisterArray(4, -1004),
164                         1 },
165                 new Object[] { IllegalArgumentException.class, ValueType.UINT32, shortArrayToRegisterArray(4, -1004),
166                         2 },
167                 new Object[] { IllegalArgumentException.class, ValueType.UINT32, shortArrayToRegisterArray(0, 0, 0),
168                         2 },
169                 //
170                 // INT32_SWAP
171                 //
172                 new Object[] { new DecimalType("1.0"), ValueType.INT32_SWAP, shortArrayToRegisterArray(1, 0), 0 },
173                 new Object[] { new DecimalType("2.0"), ValueType.INT32_SWAP, shortArrayToRegisterArray(2, 0), 0 },
174                 new Object[] { new DecimalType("-1004"), ValueType.INT32_SWAP,
175                         // -1004 = 0xFFFFFC14 (32bit) =
176                         shortArrayToRegisterArray(0xFC14, 0xFFFF), 0 },
177                 new Object[] { new DecimalType("64000"), ValueType.INT32_SWAP, shortArrayToRegisterArray(64000, 0), 0 },
178                 new Object[] { new DecimalType("-1004"), ValueType.INT32_SWAP,
179                         // -1004 = 0xFFFFFC14 (32bit) =
180                         shortArrayToRegisterArray(0x4, 0xFC14, 0xFFFF), 1 },
181                 new Object[] { new DecimalType("-1004"), ValueType.INT32_SWAP,
182                         // -1004 = 0xFFFFFC14 (32bit) =
183                         shortArrayToRegisterArray(0xFC14, 0xFFFF, 0x4), 0 },
184                 new Object[] { IllegalArgumentException.class, ValueType.INT32_SWAP,
185                         shortArrayToRegisterArray(4, -1004), 1 },
186                 new Object[] { IllegalArgumentException.class, ValueType.INT32_SWAP,
187                         shortArrayToRegisterArray(4, -1004), 2 },
188                 new Object[] { IllegalArgumentException.class, ValueType.INT32_SWAP, shortArrayToRegisterArray(0, 0, 0),
189                         2 },
190                 //
191                 // UINT32_SWAP
192                 //
193                 new Object[] { new DecimalType("1.0"), ValueType.UINT32_SWAP, shortArrayToRegisterArray(1, 0), 0 },
194                 new Object[] { new DecimalType("2.0"), ValueType.UINT32_SWAP, shortArrayToRegisterArray(2, 0), 0 },
195                 new Object[] { new DecimalType("4294966292"), ValueType.UINT32_SWAP,
196                         // 4294966292 = 0xFFFFFC14 (32bit) =
197                         shortArrayToRegisterArray(0xFC14, 0xFFFF), 0 },
198                 new Object[] { new DecimalType("64000"), ValueType.UINT32_SWAP, shortArrayToRegisterArray(64000, 0),
199                         0 },
200                 new Object[] {
201                         // out of bounds of unsigned 16bit (0 to 65,535)
202                         new DecimalType("70004"),
203                         // 70004 -> 0x00011174 (32bit) -> 0x1174 (16bit)
204                         ValueType.UINT32_SWAP, shortArrayToRegisterArray(4468, 1), 0 },
205                 new Object[] { new DecimalType("4294966292"), ValueType.UINT32_SWAP,
206                         // 4294966292 = 0xFFFFFC14 (32bit) =
207                         shortArrayToRegisterArray(0xFC14, 0xFFFF, 0x5), 0 },
208                 new Object[] { new DecimalType("4294966292"), ValueType.UINT32_SWAP,
209                         // 4294966292 = 0xFFFFFC14 (32bit) =
210                         shortArrayToRegisterArray(0x5, 0xFC14, 0xFFFF), 1 },
211                 new Object[] { IllegalArgumentException.class, ValueType.UINT32_SWAP,
212                         shortArrayToRegisterArray(4, -1004), 1 },
213                 new Object[] { IllegalArgumentException.class, ValueType.UINT32_SWAP,
214                         shortArrayToRegisterArray(4, -1004), 2 },
215                 new Object[] { IllegalArgumentException.class, ValueType.UINT32_SWAP,
216                         shortArrayToRegisterArray(0, 0, 0), 2 },
217                 //
218                 // FLOAT32
219                 //
220                 new Object[] { new DecimalType("1.0"), ValueType.FLOAT32, shortArrayToRegisterArray(0x3F80, 0x0000),
221                         0 },
222                 new Object[] { new DecimalType(1.6f), ValueType.FLOAT32, shortArrayToRegisterArray(0x3FCC, 0xCCCD), 0 },
223                 new Object[] { new DecimalType(2.6f), ValueType.FLOAT32, shortArrayToRegisterArray(0x4026, 0x6666), 0 },
224                 new Object[] { new DecimalType(-1004.4f), ValueType.FLOAT32, shortArrayToRegisterArray(0xC47B, 0x199A),
225                         0 },
226                 new Object[] { new DecimalType("64000"), ValueType.FLOAT32, shortArrayToRegisterArray(0x477A, 0x0000),
227                         0 },
228                 new Object[] {
229                         // out of bounds of unsigned 16bit (0 to 65,535)
230                         new DecimalType(70004.4f), ValueType.FLOAT32, shortArrayToRegisterArray(0x4788, 0xBA33), 0 },
231                 new Object[] {
232                         // out of bounds of unsigned 32bit (0 to 4,294,967,295)
233                         new DecimalType("5000000000"), ValueType.FLOAT32, shortArrayToRegisterArray(0x4F95, 0x02F9),
234                         0 },
235                 new Object[] { new DecimalType(-1004.4f), ValueType.FLOAT32,
236                         shortArrayToRegisterArray(0x4, 0xC47B, 0x199A), 1 },
237                 new Object[] { new DecimalType(-1004.4f), ValueType.FLOAT32,
238                         shortArrayToRegisterArray(0xC47B, 0x199A, 0x4), 0 },
239                 new Object[] { // equivalent of NaN
240                         Optional.empty(), ValueType.FLOAT32, shortArrayToRegisterArray(0x7fc0, 0x0000), 0 },
241                 new Object[] { new DecimalType(-1004.4f), ValueType.FLOAT32,
242                         shortArrayToRegisterArray(0x4, 0x0, 0x0, 0x0, 0xC47B, 0x199A), 4 },
243                 new Object[] { IllegalArgumentException.class, ValueType.FLOAT32, shortArrayToRegisterArray(4, -1004),
244                         1 },
245                 new Object[] { IllegalArgumentException.class, ValueType.FLOAT32, shortArrayToRegisterArray(4, -1004),
246                         2 },
247                 new Object[] { IllegalArgumentException.class, ValueType.FLOAT32, shortArrayToRegisterArray(0, 0, 0),
248                         2 },
249                 //
250                 // FLOAT32_SWAP
251                 //
252                 new Object[] { new DecimalType("1.0"), ValueType.FLOAT32_SWAP,
253                         shortArrayToRegisterArray(0x0000, 0x3F80), 0 },
254                 new Object[] { new DecimalType(1.6f), ValueType.FLOAT32_SWAP, shortArrayToRegisterArray(0xCCCD, 0x3FCC),
255                         0 },
256                 new Object[] { new DecimalType(2.6f), ValueType.FLOAT32_SWAP, shortArrayToRegisterArray(0x6666, 0x4026),
257                         0 },
258                 new Object[] { new DecimalType(-1004.4f), ValueType.FLOAT32_SWAP,
259                         shortArrayToRegisterArray(0x199A, 0xC47B), 0 },
260                 new Object[] { new DecimalType("64000"), ValueType.FLOAT32_SWAP,
261                         shortArrayToRegisterArray(0x0000, 0x477A), 0 },
262                 new Object[] { // equivalent of NaN
263                         Optional.empty(), ValueType.FLOAT32_SWAP, shortArrayToRegisterArray(0x0000, 0x7fc0), 0 },
264                 new Object[] {
265                         // out of bounds of unsigned 16bit (0 to 65,535)
266                         new DecimalType(70004.4f), ValueType.FLOAT32_SWAP, shortArrayToRegisterArray(0xBA33, 0x4788),
267                         0 },
268                 new Object[] {
269                         // out of bounds of unsigned 32bit (0 to 4,294,967,295)
270                         new DecimalType("5000000000"), ValueType.FLOAT32_SWAP,
271                         shortArrayToRegisterArray(0x02F9, 0x4F95), 0 },
272                 new Object[] { new DecimalType(-1004.4f), ValueType.FLOAT32_SWAP,
273                         shortArrayToRegisterArray(0x4, 0x199A, 0xC47B), 1 },
274                 new Object[] { new DecimalType(-1004.4f), ValueType.FLOAT32_SWAP,
275                         shortArrayToRegisterArray(0x199A, 0xC47B, 0x4), 0 },
276                 new Object[] { IllegalArgumentException.class, ValueType.FLOAT32_SWAP,
277                         shortArrayToRegisterArray(4, -1004), 1 },
278                 new Object[] { IllegalArgumentException.class, ValueType.FLOAT32_SWAP,
279                         shortArrayToRegisterArray(4, -1004), 2 },
280                 new Object[] { IllegalArgumentException.class, ValueType.FLOAT32_SWAP,
281                         shortArrayToRegisterArray(0, 0, 0), 2 },
282
283                 //
284                 // INT64
285                 //
286                 new Object[] { new DecimalType("1.0"), ValueType.INT64, shortArrayToRegisterArray(0, 0, 0, 1), 0 },
287                 new Object[] { new DecimalType("2.0"), ValueType.INT64, shortArrayToRegisterArray(0, 0, 0, 2), 0 },
288                 new Object[] { new DecimalType("-1004"), ValueType.INT64,
289                         shortArrayToRegisterArray(0xFFFF, 0xFFFF, 0xFFFF, 0xFC14), 0 },
290                 new Object[] { new DecimalType("64000"), ValueType.INT64, shortArrayToRegisterArray(0, 0, 0, 64000),
291                         0 },
292                 new Object[] {
293                         // out of bounds of unsigned 32bit
294                         new DecimalType("34359738368"), ValueType.INT64, shortArrayToRegisterArray(0x0, 0x8, 0x0, 0x0),
295                         0 },
296                 new Object[] { new DecimalType("-2322243636186679031"), ValueType.INT64,
297                         shortArrayToRegisterArray(0xDFC5, 0xBBB7, 0x772E, 0x7909), 0 },
298                 // would read over the registers
299                 new Object[] { IllegalArgumentException.class, ValueType.INT64,
300                         shortArrayToRegisterArray(0xDFC5, 0xBBB7, 0x772E, 0x7909), 1 },
301                 // would read over the registers
302                 new Object[] { IllegalArgumentException.class, ValueType.INT64,
303                         shortArrayToRegisterArray(0xDFC5, 0xBBB7, 0x772E, 0x7909), 2 },
304                 // 4 registers expected, only 3 available
305                 new Object[] { IllegalArgumentException.class, ValueType.INT64,
306                         shortArrayToRegisterArray(0xDFC5, 0xBBB7, 0x772E), 0 },
307
308                 //
309                 // UINT64
310                 //
311                 new Object[] { new DecimalType("1.0"), ValueType.UINT64, shortArrayToRegisterArray(0, 0, 0, 1), 0 },
312                 new Object[] { new DecimalType("2.0"), ValueType.UINT64, shortArrayToRegisterArray(0, 0, 0, 2), 0 },
313                 new Object[] { new DecimalType("18446744073709550612"), ValueType.UINT64,
314                         shortArrayToRegisterArray(0xFFFF, 0xFFFF, 0xFFFF, 0xFC14), 0 },
315                 new Object[] { new DecimalType("64000"), ValueType.UINT64, shortArrayToRegisterArray(0, 0, 0, 64000),
316                         0 },
317                 new Object[] {
318                         // out of bounds of unsigned 32bit
319                         new DecimalType("34359738368"), ValueType.UINT64, shortArrayToRegisterArray(0x0, 0x8, 0x0, 0x0),
320                         0 },
321                 new Object[] { new DecimalType("16124500437522872585"), ValueType.UINT64,
322                         shortArrayToRegisterArray(0xDFC5, 0xBBB7, 0x772E, 0x7909), 0 },
323
324                 //
325                 // INT64_SWAP
326                 //
327                 new Object[] { new DecimalType("1.0"), ValueType.INT64_SWAP, shortArrayToRegisterArray(1, 0, 0, 0), 0 },
328                 new Object[] { new DecimalType("2.0"), ValueType.INT64_SWAP, shortArrayToRegisterArray(2, 0, 0, 0), 0 },
329                 new Object[] { new DecimalType("-1004"), ValueType.INT64_SWAP,
330                         shortArrayToRegisterArray(0xFC14, 0xFFFF, 0xFFFF, 0xFFFF), 0 },
331                 new Object[] { new DecimalType("64000"), ValueType.INT64_SWAP,
332                         shortArrayToRegisterArray(64000, 0, 0, 0), 0 },
333                 new Object[] {
334                         // out of bounds of unsigned 32bit
335                         new DecimalType("34359738368"),
336                         // 70004 -> 0x00011174 (32bit) -> 0x1174 (16bit)
337                         ValueType.INT64_SWAP, shortArrayToRegisterArray(0x0, 0x0, 0x8, 0x0), 0 },
338                 new Object[] { new DecimalType("-2322243636186679031"), ValueType.INT64_SWAP,
339
340                         shortArrayToRegisterArray(0x7909, 0x772E, 0xBBB7, 0xDFC5), 0 },
341
342                 //
343                 // UINT64_SWAP
344                 //
345                 new Object[] { new DecimalType("1.0"), ValueType.UINT64_SWAP, shortArrayToRegisterArray(1, 0, 0, 0),
346                         0 },
347                 new Object[] { new DecimalType("2.0"), ValueType.UINT64_SWAP, shortArrayToRegisterArray(2, 0, 0, 0),
348                         0 },
349                 new Object[] { new DecimalType("18446744073709550612"), ValueType.UINT64_SWAP,
350                         shortArrayToRegisterArray(0xFC14, 0xFFFF, 0xFFFF, 0xFFFF), 0 },
351                 new Object[] { new DecimalType("64000"), ValueType.UINT64_SWAP,
352                         shortArrayToRegisterArray(64000, 0, 0, 0), 0 },
353                 new Object[] {
354                         // out of bounds of unsigned 32bit
355                         new DecimalType("34359738368"), ValueType.UINT64_SWAP,
356                         shortArrayToRegisterArray(0x0, 0x0, 0x8, 0x0), 0 },
357                 new Object[] {
358                         // out of bounds of unsigned 64bit
359                         new DecimalType("16124500437522872585"), ValueType.UINT64_SWAP,
360                         shortArrayToRegisterArray(0x7909, 0x772E, 0xBBB7, 0xDFC5), 0 })
361                 .collect(Collectors.toList()));
362     }
363
364     @SuppressWarnings({ "unchecked", "rawtypes" })
365     @ParameterizedTest
366     @MethodSource("data")
367     public void testCommandToRegisters(Object expectedResult, ValueType type, ModbusRegisterArray registers,
368             int index) {
369         if (expectedResult instanceof Class && Exception.class.isAssignableFrom((Class) expectedResult)) {
370             assertThrows((Class) expectedResult,
371                     () -> ModbusBitUtilities.extractStateFromRegisters(registers, index, type));
372             return;
373         }
374
375         Optional<@NonNull DecimalType> actualState = ModbusBitUtilities.extractStateFromRegisters(registers, index,
376                 type);
377         // Wrap given expectedResult to Optional, if necessary
378         Optional<@NonNull DecimalType> expectedStateWrapped = expectedResult instanceof DecimalType
379                 ? Optional.of((DecimalType) expectedResult)
380                 : (Optional<@NonNull DecimalType>) expectedResult;
381         assertThat(String.format("registers=%s, index=%d, type=%s", registers, index, type), actualState,
382                 is(equalTo(expectedStateWrapped)));
383     }
384 }