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.onewire.device;
15 import static org.junit.Assert.*;
16 import static org.mockito.ArgumentMatchers.eq;
17 import static org.openhab.binding.onewire.internal.OwBindingConstants.*;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.junit.Assert;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.mockito.ArgumentCaptor;
26 import org.mockito.InOrder;
27 import org.mockito.Mockito;
28 import org.openhab.binding.onewire.internal.OwException;
29 import org.openhab.binding.onewire.internal.device.BAE0910;
30 import org.openhab.binding.onewire.internal.owserver.OwserverDeviceParameter;
31 import org.openhab.core.config.core.Configuration;
32 import org.openhab.core.library.types.DecimalType;
33 import org.openhab.core.library.types.OnOffType;
34 import org.openhab.core.library.types.QuantityType;
35 import org.openhab.core.thing.type.ChannelTypeUID;
36 import org.openhab.core.types.State;
39 * Tests cases for {@link BAE0910}.
41 * @author Jan N. Klug - Initial contribution
44 public class BAE0910Test extends DeviceTestParent<BAE0910> {
46 public void setupMocks() {
47 setupMocks(THING_TYPE_BAE091X, BAE0910.class);
53 public void counter() {
54 addChannel(CHANNEL_COUNTER, "Number");
55 final BAE0910 testDevice = instantiateDevice();
56 final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
59 Mockito.when(mockBridgeHandler.checkPresence(testSensorId)).thenReturn(OnOffType.ON);
61 mockBridgeHandler.readDecimalType(eq(testSensorId), eq(new OwserverDeviceParameter("/counter"))))
62 .thenReturn(new DecimalType(34567));
64 testDevice.enableChannel(CHANNEL_COUNTER);
65 testDevice.configureChannels(mockBridgeHandler);
68 ArgumentCaptor<State> stateArgumentCaptor = ArgumentCaptor.forClass(State.class);
69 testDevice.refresh(mockBridgeHandler, true);
70 inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
71 eq(new OwserverDeviceParameter("/counter")));
72 inOrder.verify(mockThingHandler).postUpdate(eq(CHANNEL_COUNTER), stateArgumentCaptor.capture());
73 assertEquals(new DecimalType(34567), stateArgumentCaptor.getValue());
76 assertFalse(testDevice.writeChannel(mockBridgeHandler, CHANNEL_COUNTER, new DecimalType(12345)));
78 inOrder.verifyNoMoreInteractions();
79 } catch (OwException e) {
80 Assert.fail("caught unexpected OwException");
84 // pin 2: digital2 or pwm1
87 public void digitalOut2() {
88 addChannel(CHANNEL_DIGITAL2, "Switch");
89 digitalBaseChannel(CHANNEL_DIGITAL2, bitSet(3, 4), 0, "/out", bitSet(0), true);
94 pwmBaseChannel(CHANNEL_PWM_FREQ2, CHANNEL_PWM_DUTY4, "/period2", "/duty4", 2);
97 // pin 6: pio or pwm 3
100 public void digital6PioIn() {
101 Map<String, Object> channelConfig = new HashMap<>();
102 channelConfig.put("pulldevice", "pulldown");
103 channelConfig.put("mode", "input");
104 addChannel(CHANNEL_DIGITAL6, "Switch", new Configuration(channelConfig));
105 digitalBaseChannel(CHANNEL_DIGITAL6, bitSet(1, 2, 3, 4), 1, "/pio", bitSet(0), false);
109 public void digital6PioOut() {
110 Map<String, Object> channelConfig = new HashMap<>();
111 channelConfig.put("mode", "output");
112 addChannel(CHANNEL_DIGITAL6, "Switch", new Configuration(channelConfig));
113 digitalBaseChannel(CHANNEL_DIGITAL6, bitSet(0, 3, 4), 1, "/pio", bitSet(0), true);
118 pwmBaseChannel(CHANNEL_PWM_FREQ1, CHANNEL_PWM_DUTY3, "/period1", "/duty3", 1);
121 // pin 7: analog, output, pwm2
124 public void analog() {
125 Map<String, Object> channelConfig = new HashMap<>();
126 channelConfig.put("hires", "true");
127 addChannel(CHANNEL_VOLTAGE, "Number:ElectricPotential", new Configuration(channelConfig));
129 final BAE0910 testDevice = instantiateDevice();
130 final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
133 Mockito.when(mockBridgeHandler.checkPresence(testSensorId)).thenReturn(OnOffType.ON);
134 Mockito.when(mockBridgeHandler.readDecimalType(eq(testSensorId), eq(new OwserverDeviceParameter("/adc"))))
135 .thenReturn(new DecimalType(5.2));
137 testDevice.enableChannel(CHANNEL_VOLTAGE);
138 testDevice.configureChannels(mockBridgeHandler);
140 // test configuration
141 assertEquals(bitSet(3, 4), checkConfiguration(2));
144 ArgumentCaptor<State> stateArgumentCaptor = ArgumentCaptor.forClass(State.class);
145 testDevice.refresh(mockBridgeHandler, true);
146 inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
147 eq(new OwserverDeviceParameter("/adc")));
148 inOrder.verify(mockThingHandler).postUpdate(eq(CHANNEL_VOLTAGE), stateArgumentCaptor.capture());
149 assertEquals(new QuantityType<>("5.2 V"), stateArgumentCaptor.getValue());
151 // write (should fail)
152 assertFalse(testDevice.writeChannel(mockBridgeHandler, CHANNEL_VOLTAGE, new QuantityType<>("3 V")));
154 inOrder.verifyNoMoreInteractions();
155 } catch (OwException e) {
156 Assert.fail("caught unexpected OwException");
161 public void digitalOut7() {
162 addChannel(CHANNEL_DIGITAL7, "Switch");
163 digitalBaseChannel(CHANNEL_DIGITAL7, bitSet(4), 4, "/tpm2c", bitSet(4, 7), true);
168 pwmBaseChannel(CHANNEL_PWM_FREQ2, CHANNEL_PWM_DUTY2, "/period2", "/duty2", 2);
171 // pin 8: digital in, digital out or pwm
174 public void digitalIn8() {
175 addChannel(CHANNEL_DIGITAL8, "Switch", new ChannelTypeUID(BINDING_ID, "bae-in"));
176 digitalBaseChannel(CHANNEL_DIGITAL8, bitSet(4, 5), 3, "/tpm1c", bitSet(4, 5, 7), false);
180 public void digitalOut8() {
181 addChannel(CHANNEL_DIGITAL8, "Switch");
182 digitalBaseChannel(CHANNEL_DIGITAL8, bitSet(4), 3, "/tpm1c", bitSet(4, 7), true);
187 pwmBaseChannel(CHANNEL_PWM_FREQ1, CHANNEL_PWM_DUTY1, "/period1", "/duty1", 1);
191 * base test for digital channels
193 * @param channel channel name
194 * @param configBitSet expected config register
195 * @param configRegister config register number
196 * @param channelParam channel parameter
197 * @param returnBitSet which bitset should be returned on read
198 * @param isOutput if this channel is an output
200 private void digitalBaseChannel(String channel, BitSet configBitSet, int configRegister, String channelParam,
201 BitSet returnBitSet, boolean isOutput) {
202 final BAE0910 testDevice = instantiateDevice();
203 final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
206 Mockito.when(mockBridgeHandler.checkPresence(testSensorId)).thenReturn(OnOffType.ON);
207 Mockito.when(mockBridgeHandler.readBitSet(eq(testSensorId), eq(new OwserverDeviceParameter(channelParam))))
208 .thenReturn(returnBitSet);
210 testDevice.enableChannel(channel);
211 testDevice.configureChannels(mockBridgeHandler);
213 // test configuration
214 assertEquals(configBitSet, checkConfiguration(configRegister));
217 ArgumentCaptor<State> stateArgumentCaptor = ArgumentCaptor.forClass(State.class);
218 testDevice.refresh(mockBridgeHandler, true);
219 inOrder.verify(mockBridgeHandler).readBitSet(eq(testSensorId),
220 eq(new OwserverDeviceParameter(channelParam)));
221 inOrder.verify(mockThingHandler).postUpdate(eq(channel), stateArgumentCaptor.capture());
222 assertEquals(OnOffType.ON, stateArgumentCaptor.getValue());
226 ArgumentCaptor<BitSet> bitSetArgumentCaptor = ArgumentCaptor.forClass(BitSet.class);
227 assertTrue(testDevice.writeChannel(mockBridgeHandler, channel, OnOffType.ON));
228 inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId),
229 eq(new OwserverDeviceParameter(channelParam)), bitSetArgumentCaptor.capture());
230 assertEquals(returnBitSet, bitSetArgumentCaptor.getValue());
232 assertFalse(testDevice.writeChannel(mockBridgeHandler, channel, OnOffType.ON));
235 inOrder.verifyNoMoreInteractions();
236 } catch (OwException e) {
237 Assert.fail("caught unexpected OwException");
242 * base test case for PWM channels
244 * @param freqChannel channel name for frequency
245 * @param dutyChannel channel name for duty cycle
246 * @param freqParam owfs parameter for frequency
247 * @param dutyParam owfs parameter for duty cycle
248 * @param registerIndex index for TPM configuration register
250 private void pwmBaseChannel(String freqChannel, String dutyChannel, String freqParam, String dutyParam,
252 Map<String, Object> channelConfig = new HashMap<>();
253 channelConfig.put("prescaler", 5);
254 addChannel(freqChannel, "Number:Frequency", new Configuration(channelConfig));
255 addChannel(dutyChannel, "Number:Dimensionless");
257 final BAE0910 testDevice = instantiateDevice();
258 final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
261 Mockito.when(mockBridgeHandler.checkPresence(testSensorId)).thenReturn(OnOffType.ON);
263 mockBridgeHandler.readDecimalType(eq(testSensorId), eq(new OwserverDeviceParameter(freqParam))))
264 .thenReturn(new DecimalType(32768));
266 mockBridgeHandler.readDecimalType(eq(testSensorId), eq(new OwserverDeviceParameter(dutyParam))))
267 .thenReturn(new DecimalType(16384));
269 testDevice.enableChannel(freqChannel);
270 testDevice.enableChannel(dutyChannel);
271 testDevice.configureChannels(mockBridgeHandler);
273 // test configuration
274 assertEquals(bitSet(0, 2), checkConfiguration(registerIndex + 2));
277 ArgumentCaptor<State> stateArgumentCaptor = ArgumentCaptor.forClass(State.class);
278 testDevice.refresh(mockBridgeHandler, true);
279 inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
280 eq(new OwserverDeviceParameter(freqParam)));
281 inOrder.verify(mockThingHandler).postUpdate(eq(freqChannel), stateArgumentCaptor.capture());
282 assertEquals(new QuantityType<>("15.2587890625 Hz"), stateArgumentCaptor.getValue());
283 inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
284 eq(new OwserverDeviceParameter(dutyParam)));
285 inOrder.verify(mockThingHandler).postUpdate(eq(dutyChannel), stateArgumentCaptor.capture());
286 assertEquals(new QuantityType<>("50 %"), stateArgumentCaptor.getValue());
289 ArgumentCaptor<DecimalType> decimalTypeArgumentCaptor = ArgumentCaptor.forClass(DecimalType.class);
290 assertTrue(testDevice.writeChannel(mockBridgeHandler, freqChannel, new QuantityType<>("50000 Hz")));
291 inOrder.verify(mockBridgeHandler).writeDecimalType(eq(testSensorId),
292 eq(new OwserverDeviceParameter(freqParam)), decimalTypeArgumentCaptor.capture());
293 assertEquals(new DecimalType(10), decimalTypeArgumentCaptor.getValue());
294 testDevice.writeChannel(mockBridgeHandler, dutyChannel, new QuantityType<>("25 %"));
295 inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
296 eq(new OwserverDeviceParameter(freqParam)));
297 inOrder.verify(mockBridgeHandler).writeDecimalType(eq(testSensorId),
298 eq(new OwserverDeviceParameter(dutyParam)), decimalTypeArgumentCaptor.capture());
299 assertEquals(new DecimalType(8192), decimalTypeArgumentCaptor.getValue());
301 inOrder.verifyNoMoreInteractions();
302 } catch (OwException e) {
303 Assert.fail("caught unexpected OwException");
308 * check if all registers are written and return one
310 * @param registerIndex number of register to return
311 * @return this register's BitSet
312 * @throws OwException
314 private BitSet checkConfiguration(int registerIndex) throws OwException {
315 ArgumentCaptor<BitSet> configArgumentCaptor = ArgumentCaptor.forClass(BitSet.class);
316 final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
318 inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/outc")),
319 configArgumentCaptor.capture());
320 inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/pioc")),
321 configArgumentCaptor.capture());
322 inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/adcc")),
323 configArgumentCaptor.capture());
324 inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/tpm1c")),
325 configArgumentCaptor.capture());
326 inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/tpm2c")),
327 configArgumentCaptor.capture());
328 return configArgumentCaptor.getAllValues().get(registerIndex);
332 * BitSet with pre-set bits
334 * @param bits which bits to set
337 private BitSet bitSet(int... bits) {
338 BitSet bitSet = new BitSet(8);
339 Arrays.stream(bits).forEach(b -> bitSet.set(b));