2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.modbus.e3dc.internal.handler;
15 import static org.mockito.Mockito.*;
17 import java.nio.ByteBuffer;
18 import java.util.HashMap;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.junit.Test;
22 import org.mockito.ArgumentMatchers;
23 import org.openhab.core.config.core.Configuration;
24 import org.openhab.core.thing.Bridge;
25 import org.openhab.core.thing.Thing;
26 import org.openhab.core.thing.ThingStatus;
27 import org.openhab.core.thing.ThingStatusDetail;
28 import org.openhab.core.thing.ThingStatusInfo;
29 import org.openhab.core.thing.ThingUID;
30 import org.openhab.core.thing.binding.ThingHandlerCallback;
31 import org.openhab.io.transport.modbus.AsyncModbusFailure;
32 import org.openhab.io.transport.modbus.AsyncModbusReadResult;
33 import org.openhab.io.transport.modbus.ModbusReadRequestBlueprint;
34 import org.openhab.io.transport.modbus.ModbusRegister;
35 import org.openhab.io.transport.modbus.ModbusRegisterArray;
38 * The {@link E3DCHandlerStateTest} Test State handling of Handler if different results occurs
40 * @author Bernd Weymann - Initial contribution
43 public class E3DCHandlerStateTest {
44 ThingStatusInfo unknownStatus = new ThingStatusInfo(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, null);
45 ThingStatusInfo onlineStatus = new ThingStatusInfo(ThingStatus.ONLINE, ThingStatusDetail.NONE, null);
46 ThingStatusInfo offlineStatus = new ThingStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
47 E3DCThingHandler.DATA_READ_ERROR);
50 public void testStatusChain() {
51 Bridge bridge = mock(Bridge.class);
52 ThingUID uid = new ThingUID("modbus", "e3dc", "powerplant");
53 when(bridge.getUID()).thenReturn(uid);
54 ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
55 E3DCThingHandler handler = new E3DCThingHandler(bridge);
56 handler.setCallback(callback);
58 HashMap<String, Object> map = new HashMap<String, Object>();
59 map.put("refresh", 2000);
60 Configuration config = new Configuration(map);
61 when(bridge.getConfiguration()).thenReturn(config);
63 verify(callback).statusUpdated(ArgumentMatchers.eq((Thing) bridge), ArgumentMatchers.eq(unknownStatus));
64 // Initializing is ongoing - now simulate info and data callback
66 handler.handleInfoResult(getInfoResult());
67 verify(callback).statusUpdated(ArgumentMatchers.eq((Thing) bridge), ArgumentMatchers.eq(unknownStatus));
68 handler.handleDataResult(getDataResult());
69 verify(callback, times(1)).statusUpdated(ArgumentMatchers.eq((Thing) bridge),
70 ArgumentMatchers.eq(onlineStatus));
73 // call it a few times - ensure at the end of the test that "ONLINE" status is raised only 2 times and not all
75 handler.handleDataResult(getDataResult());
76 handler.handleDataResult(getDataResult());
77 handler.handleDataResult(getDataResult());
79 // simulate one wrong data result
80 handler.handleDataFailure(getFailResult());
81 verify(callback).statusUpdated(ArgumentMatchers.eq((Thing) bridge), ArgumentMatchers.eq(offlineStatus));
84 handler.handleDataResult(getDataResult());
85 verify(callback, times(2)).statusUpdated(ArgumentMatchers.eq((Thing) bridge),
86 ArgumentMatchers.eq(onlineStatus));
89 private AsyncModbusReadResult getInfoResult() {
90 byte[] infoBlockBytes = new byte[] { -29, -36, 1, 2, 0, -120, 69, 51, 47, 68, 67, 32, 71, 109, 98, 72, 0, 0, 0,
91 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 49, 48, 32, 69, 32, 65, 73, 79, 0, 0, 0, 0,
92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 78, 73, 78, 73, 84, 73, 65, 76, 73, 90, 69,
93 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 49, 48, 95, 50, 48, 50, 48, 95, 48, 52,
94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
95 ByteBuffer infoWrap = ByteBuffer.wrap(infoBlockBytes);
96 ModbusRegister[] infoBlock = new ModbusRegister[infoBlockBytes.length / 2];
97 for (int i = 0; i < infoBlock.length; i++) {
98 infoBlock[i] = new ModbusRegister(infoWrap.get(), infoWrap.get());
100 ModbusReadRequestBlueprint readRequest = mock(ModbusReadRequestBlueprint.class);
101 return new AsyncModbusReadResult(readRequest, new ModbusRegisterArray(infoBlock));
104 private AsyncModbusReadResult getDataResult() {
105 byte[] dataBlockBytes = new byte[] { 0, -14, 0, 0, -2, -47, -1, -1, 2, 47, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 99, 99, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107 1, 125, 2, 21, 0, 0, 0, 27, 0, 26, 0, 0, 0, 103, 0, -117, 0, 0 };
108 ByteBuffer dataWrap = ByteBuffer.wrap(dataBlockBytes);
109 ModbusRegister[] dataBlock = new ModbusRegister[dataBlockBytes.length / 2];
110 for (int i = 0; i < dataBlock.length; i++) {
111 dataBlock[i] = new ModbusRegister(dataWrap.get(), dataWrap.get());
113 ModbusReadRequestBlueprint readRequest = mock(ModbusReadRequestBlueprint.class);
114 return new AsyncModbusReadResult(readRequest, new ModbusRegisterArray(dataBlock));
117 private AsyncModbusFailure<ModbusReadRequestBlueprint> getFailResult() {
118 ModbusReadRequestBlueprint readRequest = mock(ModbusReadRequestBlueprint.class);
119 return new AsyncModbusFailure<ModbusReadRequestBlueprint>(readRequest, new Exception("Something failed!"));