2 * Copyright (c) 2010-2021 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.bmwconnecteddrive.internal.dto;
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*;
18 import java.util.HashMap;
19 import java.util.List;
22 import javax.measure.Unit;
23 import javax.measure.quantity.Length;
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType;
28 import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip;
29 import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer;
30 import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants;
31 import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter;
32 import org.openhab.core.library.types.DateTimeType;
33 import org.openhab.core.library.types.QuantityType;
34 import org.openhab.core.library.unit.ImperialUnits;
35 import org.openhab.core.library.unit.Units;
36 import org.openhab.core.thing.ChannelUID;
37 import org.openhab.core.types.State;
39 import com.google.gson.Gson;
42 * The {@link TripWrapper} Test json responses from ConnectedDrive Portal
44 * @author Bernd Weymann - Initial contribution
47 @SuppressWarnings("null")
48 public class TripWrapper {
49 private static final Gson GSON = new Gson();
50 private static final Unit<Length> MILES = ImperialUnits.MILE;
52 private LastTrip lastTrip;
53 private boolean imperial;
54 private boolean isElectric;
55 private boolean hasFuel;
56 private boolean isHybrid;
58 private Map<String, State> specialHandlingMap = new HashMap<String, State>();
60 public TripWrapper(String type, boolean imperial, String statusJson) {
61 this.imperial = imperial;
62 hasFuel = type.equals(VehicleType.CONVENTIONAL.toString()) || type.equals(VehicleType.PLUGIN_HYBRID.toString())
63 || type.equals(VehicleType.ELECTRIC_REX.toString());
64 isElectric = type.equals(VehicleType.PLUGIN_HYBRID.toString())
65 || type.equals(VehicleType.ELECTRIC_REX.toString()) || type.equals(VehicleType.ELECTRIC.toString());
66 isHybrid = hasFuel && isElectric;
67 LastTripContainer container = GSON.fromJson(statusJson, LastTripContainer.class);
68 assertNotNull(container);
69 assertNotNull(container.lastTrip);
70 lastTrip = container.lastTrip;
74 * Test results auctomatically against json values
80 public boolean checkResults(@Nullable List<ChannelUID> channels, @Nullable List<State> states) {
81 assertNotNull(channels);
82 assertNotNull(states);
83 assertTrue(channels.size() == states.size(), "Same list sizes");
84 for (int i = 0; i < channels.size(); i++) {
85 checkResult(channels.get(i), states.get(i));
91 * Add a specific check for a value e.g. hard coded "Upcoming Service" in order to check the right ordering
96 public TripWrapper append(Map<String, State> compareMap) {
97 specialHandlingMap.putAll(compareMap);
101 @SuppressWarnings({ "unchecked", "rawtypes" })
102 private void checkResult(ChannelUID channelUID, State state) {
103 String cUid = channelUID.getIdWithoutGroup();
104 QuantityType<Length> qt;
108 assertTrue(state instanceof DateTimeType);
109 dtt = ((DateTimeType) state);
110 DateTimeType expected = DateTimeType.valueOf(Converter.getLocalDateTimeWithoutOffest(lastTrip.date));
111 assertEquals(expected.toString(), dtt.toString(), "Trip Date");
114 assertTrue(state instanceof QuantityType);
115 qt = ((QuantityType) state);
116 assertEquals(Units.MINUTE, qt.getUnit(), "Minute");
117 assertEquals(lastTrip.duration, qt.floatValue(), 0.1, "Duration");
120 assertTrue(state instanceof QuantityType);
121 qt = ((QuantityType) state);
123 assertEquals(MILES, qt.getUnit(), "Miles");
124 assertEquals(lastTrip.totalDistance / Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1,
128 assertEquals(Constants.KILOMETRE_UNIT, qt.getUnit(), "KM");
129 assertEquals(lastTrip.totalDistance, qt.floatValue(), 0.1, "Distance");
132 case AVG_CONSUMPTION:
133 assertTrue(state instanceof QuantityType);
134 qt = ((QuantityType) state);
135 assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h");
137 assertEquals(lastTrip.avgElectricConsumption * Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1,
140 assertEquals(lastTrip.avgElectricConsumption, qt.floatValue(), 0.1, "Avg Consumption");
143 case AVG_COMBINED_CONSUMPTION:
144 assertTrue(isHybrid, "Is Hybrid");
145 assertTrue(state instanceof QuantityType);
146 qt = ((QuantityType) state);
147 assertEquals(Units.LITRE, qt.getUnit(), "Liter");
149 assertEquals(Converter.round(lastTrip.avgCombinedConsumption * Converter.MILES_TO_KM_RATIO),
150 qt.floatValue(), 0.01, "Percent");
152 assertEquals(Converter.round(lastTrip.avgCombinedConsumption), qt.floatValue(), 0.01, "Percent");
155 case AVG_RECUPERATION:
156 assertTrue(state instanceof QuantityType);
157 qt = ((QuantityType) state);
158 assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h");
160 assertEquals(lastTrip.avgRecuperation * Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1,
163 assertEquals(lastTrip.avgRecuperation, qt.floatValue(), 0.1, "Avg Recuperation");
167 // fail in case of unknown update
168 assertFalse(true, "Channel " + channelUID + " " + state + " not found");