2 * Copyright (c) 2010-2022 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.AllTrips;
29 import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer;
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.QuantityType;
33 import org.openhab.core.library.unit.ImperialUnits;
34 import org.openhab.core.library.unit.Units;
35 import org.openhab.core.thing.ChannelUID;
36 import org.openhab.core.types.State;
38 import com.google.gson.Gson;
41 * The {@link LifetimeWrapper} Test json responses from ConnectedDrive Portal
43 * @author Bernd Weymann - Initial contribution
46 @SuppressWarnings("null")
47 public class LifetimeWrapper {
48 private static final Gson GSON = new Gson();
49 private static final Unit<Length> MILES = ImperialUnits.MILE;
51 private AllTrips allTrips;
52 private boolean imperial;
53 private boolean isElectric;
54 private boolean hasFuel;
55 private boolean isHybrid;
57 private Map<String, State> specialHandlingMap = new HashMap<String, State>();
59 public LifetimeWrapper(String type, boolean imperial, String statusJson) {
60 this.imperial = imperial;
61 hasFuel = type.equals(VehicleType.CONVENTIONAL.toString()) || type.equals(VehicleType.PLUGIN_HYBRID.toString())
62 || type.equals(VehicleType.ELECTRIC_REX.toString());
63 isElectric = type.equals(VehicleType.PLUGIN_HYBRID.toString())
64 || type.equals(VehicleType.ELECTRIC_REX.toString()) || type.equals(VehicleType.ELECTRIC.toString());
65 isHybrid = hasFuel && isElectric;
66 AllTripsContainer container = GSON.fromJson(statusJson, AllTripsContainer.class);
67 assertNotNull(container);
68 assertNotNull(container.allTrips);
69 allTrips = container.allTrips;
73 * Test results auctomatically against json values
79 public boolean checkResults(@Nullable List<ChannelUID> channels, @Nullable List<State> states) {
80 assertNotNull(channels);
81 assertNotNull(states);
82 assertTrue(channels.size() == states.size(), "Same list sizes ");
83 for (int i = 0; i < channels.size(); i++) {
84 checkResult(channels.get(i), states.get(i));
90 * Add a specific check for a value e.g. hard coded "Upcoming Service" in order to check the right ordering
95 public LifetimeWrapper append(Map<String, State> compareMap) {
96 specialHandlingMap.putAll(compareMap);
100 @SuppressWarnings({ "unchecked", "rawtypes" })
101 private void checkResult(ChannelUID channelUID, State state) {
102 String cUid = channelUID.getIdWithoutGroup();
103 QuantityType<Length> qt;
105 case DISTANCE_SINCE_CHARGING:
106 assertTrue(state instanceof QuantityType);
107 qt = ((QuantityType) state);
109 assertEquals(MILES, qt.getUnit(), "Miles");
110 assertEquals(allTrips.chargecycleRange.userCurrentChargeCycle / Converter.MILES_TO_KM_RATIO,
111 qt.floatValue(), 0.1, "Distance since charging");
113 assertEquals(Constants.KILOMETRE_UNIT, qt.getUnit(), "KM");
114 assertEquals(allTrips.chargecycleRange.userCurrentChargeCycle, qt.floatValue(), 0.1,
115 "Distance since charging");
118 case SINGLE_LONGEST_DISTANCE:
119 assertTrue(state instanceof QuantityType);
120 qt = ((QuantityType) state);
122 assertEquals(MILES, qt.getUnit(), "Miles");
123 assertEquals(allTrips.chargecycleRange.userHigh / Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1,
126 assertEquals(Constants.KILOMETRE_UNIT, qt.getUnit(), "KM");
127 assertEquals(allTrips.chargecycleRange.userHigh, qt.floatValue(), 0.1, "Longest Distance");
130 case TOTAL_DRIVEN_DISTANCE:
131 assertTrue(state instanceof QuantityType);
132 qt = ((QuantityType) state);
134 assertEquals(MILES, qt.getUnit(), "Miles");
135 assertEquals(allTrips.totalElectricDistance.userTotal / Converter.MILES_TO_KM_RATIO,
136 qt.floatValue(), 0.1, "Total Electric Distance");
138 assertEquals(Constants.KILOMETRE_UNIT, qt.getUnit(), "KM");
139 assertEquals(allTrips.totalElectricDistance.userTotal, qt.floatValue(), 0.1,
140 "Total Electric Distance");
143 case AVG_CONSUMPTION:
144 assertTrue(isElectric, "Is Electric");
145 assertTrue(state instanceof QuantityType);
146 qt = ((QuantityType) state);
147 assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h");
149 assertEquals(allTrips.avgElectricConsumption.userAverage * Converter.MILES_TO_KM_RATIO,
150 qt.floatValue(), 0.1, "Avg Consumption");
152 assertEquals(allTrips.avgElectricConsumption.userAverage, qt.floatValue(), 0.1, "Avg Consumption");
155 case AVG_RECUPERATION:
156 assertTrue(isElectric, "Is Electric");
157 assertTrue(state instanceof QuantityType);
158 qt = ((QuantityType) state);
159 assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h");
161 assertEquals(allTrips.avgRecuperation.userAverage * Converter.MILES_TO_KM_RATIO, qt.floatValue(),
162 0.1, "Avg Recuperation");
164 assertEquals(allTrips.avgRecuperation.userAverage, qt.floatValue(), 0.1, "Avg Recuperation");
167 case AVG_COMBINED_CONSUMPTION:
168 assertTrue(isHybrid, "Is Hybrid");
169 assertTrue(state instanceof QuantityType);
170 qt = ((QuantityType) state);
171 assertEquals(Units.LITRE, qt.getUnit(), "Liter");
173 assertEquals(allTrips.avgCombinedConsumption.userAverage * Converter.MILES_TO_KM_RATIO,
174 qt.floatValue(), 0.1, "Avg Combined Consumption");
176 assertEquals(allTrips.avgCombinedConsumption.userAverage, qt.floatValue(), 0.1,
177 "Avg Combined Consumption");
181 // fail in case of unknown update
182 assertFalse(true, "Channel " + channelUID + " " + state + " not found");