]> git.basschouten.com Git - openhab-addons.git/blob
041fe56247ee46e22d68b17b8bb219a44a5d11e9
[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.binding.dsmr.internal.discovery;
14
15 import static org.junit.Assert.*;
16 import static org.mockito.Mockito.when;
17 import static org.mockito.MockitoAnnotations.initMocks;
18 import static org.openhab.binding.dsmr.internal.meter.DSMRMeterType.*;
19
20 import java.util.Collections;
21 import java.util.EnumSet;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.TooManyListenersException;
25 import java.util.concurrent.atomic.AtomicBoolean;
26 import java.util.concurrent.atomic.AtomicReference;
27 import java.util.stream.Collectors;
28
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.mockito.Answers;
32 import org.mockito.Mock;
33 import org.openhab.binding.dsmr.internal.TelegramReaderUtil;
34 import org.openhab.binding.dsmr.internal.device.p1telegram.P1Telegram;
35 import org.openhab.binding.dsmr.internal.device.p1telegram.P1Telegram.TelegramState;
36 import org.openhab.binding.dsmr.internal.handler.DSMRBridgeHandler;
37 import org.openhab.binding.dsmr.internal.handler.DSMRMeterHandler;
38 import org.openhab.binding.dsmr.internal.meter.DSMRMeterDescriptor;
39 import org.openhab.binding.dsmr.internal.meter.DSMRMeterType;
40 import org.openhab.core.io.transport.serial.PortInUseException;
41 import org.openhab.core.thing.Thing;
42 import org.openhab.core.thing.ThingUID;
43
44 /**
45  * Test class for {@link DSMRMeterDiscoveryService}.
46  *
47  * @author Hilbrand Bouwkamp - Initial contribution
48  */
49 public class DSMRMeterDiscoveryServiceTest {
50
51     private static final String EXPECTED_CONFIGURED_TELEGRAM = "dsmr_50";
52     private static final String UNREGISTERED_METER_TELEGRAM = "unregistered_meter";
53
54     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
55     private DSMRBridgeHandler bridge;
56     @Mock
57     private Thing thing;
58     @Mock
59     private DSMRMeterHandler meterHandler;
60
61     @Before
62     public void setUp() throws PortInUseException, TooManyListenersException {
63         initMocks(this);
64     }
65
66     /**
67      * Test if discovery reports when the user has incorrectly configured the binding with the wrong meter types.
68      * Some meters are a subset of other meters so it won't generates errors in usage, but some values will not be
69      * available to the user with the subset meter.
70      */
71     @Test
72     public void testInvalidConfiguredMeters() {
73         P1Telegram expected = TelegramReaderUtil.readTelegram(EXPECTED_CONFIGURED_TELEGRAM, TelegramState.OK);
74         AtomicReference<List<DSMRMeterType>> invalidConfiguredRef = new AtomicReference<>();
75         AtomicReference<List<DSMRMeterType>> unconfiguredRef = new AtomicReference<>();
76         DSMRMeterDiscoveryService service = new DSMRMeterDiscoveryService(bridge) {
77             @Override
78             protected void reportConfigurationValidationResults(List<DSMRMeterType> invalidConfigured,
79                     List<DSMRMeterType> unconfiguredMeters) {
80                 super.reportConfigurationValidationResults(invalidConfigured, unconfiguredMeters);
81                 invalidConfiguredRef.set(invalidConfigured);
82                 unconfiguredRef.set(unconfiguredMeters);
83             }
84         };
85
86         // Mock the invalid configuration by reading a telegram that is valid for a meter that is a subset of the
87         // expected meter.
88         List<DSMRMeterDescriptor> invalidConfiguredMeterDescriptors = EnumSet.of(DEVICE_V5, ELECTRICITY_V4_2, M3_V5_0)
89                 .stream().map(mt -> new DSMRMeterDescriptor(mt, 0)).collect(Collectors.toList());
90         List<Thing> things = invalidConfiguredMeterDescriptors.stream().map(m -> thing).collect(Collectors.toList());
91         AtomicReference<Iterator<DSMRMeterDescriptor>> detectMetersRef = new AtomicReference<>();
92         when((meterHandler).getMeterDescriptor()).then(a -> {
93             if (detectMetersRef.get() == null || !detectMetersRef.get().hasNext()) {
94                 detectMetersRef.set(invalidConfiguredMeterDescriptors.iterator());
95             }
96             return detectMetersRef.get().next();
97         });
98         when(thing.getHandler()).thenReturn(meterHandler);
99         when(bridge.getThing().getUID()).thenReturn(new ThingUID("dsmr:dsmrBridge:22e5393c"));
100         when(bridge.getThing().getThings()).thenReturn(things);
101
102         service.telegramReceived(expected);
103         assertNotNull("Should have invalid configured meters", invalidConfiguredRef.get());
104         assertTrue("Should have found specific invalid meter",
105                 invalidConfiguredRef.get().contains(DSMRMeterType.ELECTRICITY_V4_2));
106         assertNotNull("Should have undetected meters", unconfiguredRef.get());
107         assertTrue("Should have found specific undetected meter",
108                 unconfiguredRef.get().contains(DSMRMeterType.ELECTRICITY_V5_0));
109     }
110
111     /**
112      * Test if discovery correctly reports if a meter was detected that has not been registered with the energy
113      * provider. This meter doesn't report all values in telegram and therefore is not recognized as a specific
114      * meter. But reports with an empty equipment identifier.
115      */
116     @Test
117     public void testUnregisteredMeters() {
118         P1Telegram telegram = TelegramReaderUtil.readTelegram(UNREGISTERED_METER_TELEGRAM, TelegramState.OK);
119         AtomicBoolean unregisteredMeter = new AtomicBoolean(false);
120         DSMRMeterDiscoveryService service = new DSMRMeterDiscoveryService(bridge) {
121             @Override
122             protected void reportUnregisteredMeters() {
123                 super.reportUnregisteredMeters();
124                 unregisteredMeter.set(true);
125             }
126         };
127         when(bridge.getThing().getUID()).thenReturn(new ThingUID("dsmr:dsmrBridge:22e5393c"));
128         when(bridge.getThing().getThings()).thenReturn(Collections.emptyList());
129
130         service.telegramReceived(telegram);
131         assertTrue("Should have found an unregistered meter", unregisteredMeter.get());
132     }
133 }