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