]> git.basschouten.com Git - openhab-addons.git/blob
5aab32f86e9e60ace19530da297b41aeb7bb5715
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.mercedesme.internal.handler;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.mockito.Mockito.*;
17 import static org.openhab.binding.mercedesme.internal.Constants.*;
18
19 import java.util.Map;
20 import java.util.Optional;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.junit.jupiter.api.Test;
24 import org.openhab.binding.mercedesme.FileReader;
25 import org.openhab.binding.mercedesme.internal.Constants;
26 import org.openhab.binding.mercedesme.internal.MercedesMeCommandOptionProvider;
27 import org.openhab.binding.mercedesme.internal.MercedesMeStateOptionProvider;
28 import org.openhab.binding.mercedesme.internal.config.VehicleConfiguration;
29 import org.openhab.binding.mercedesme.internal.utils.Utils;
30 import org.openhab.core.events.EventPublisher;
31 import org.openhab.core.library.types.DateTimeType;
32 import org.openhab.core.library.types.DecimalType;
33 import org.openhab.core.library.types.QuantityType;
34 import org.openhab.core.thing.ChannelUID;
35 import org.openhab.core.thing.Thing;
36 import org.openhab.core.thing.ThingUID;
37 import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
38 import org.openhab.core.thing.link.ItemChannelLinkRegistry;
39 import org.openhab.core.types.RefreshType;
40
41 import com.daimler.mbcarkit.proto.VehicleEvents.VEPUpdate;
42
43 /**
44  * {@link VehicleHandlerTest} check state updates and command sending of vehicles
45  *
46  * @author Bernd Weymann - Initial contribution
47  */
48 @NonNullByDefault
49 class VehicleHandlerTest {
50
51     @Test
52     public void testBEVFullUpdateNoCapacities() {
53         Thing thingMock = mock(Thing.class);
54         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
55         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
56         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
57                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
58         vh.accountHandler = Optional.of(mock(AccountHandler.class));
59         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
60         vh.config = Optional.of(vehicleConfig);
61         ThingCallbackListener updateListener = new ThingCallbackListener();
62         vh.setCallback(updateListener);
63
64         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-EQA.json");
65         VEPUpdate update = ProtoConverter.json2Proto(json, true);
66         vh.distributeContent(update);
67
68         assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
69         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
70         assertEquals(5, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
71         assertEquals(8, updateListener.getUpdatesForGroup("windows"), "Windows Update Count");
72         assertEquals(12, updateListener.getUpdatesForGroup("trip"), "Trip Update Count");
73         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Tire Update Count");
74         assertEquals(6, updateListener.getUpdatesForGroup("service"), "Service Update Count");
75         assertEquals(7, updateListener.getUpdatesForGroup("range"), "Range Update Count");
76         assertEquals(2, updateListener.getUpdatesForGroup("position"), "Position Update Count");
77         assertEquals(5, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
78         assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
79         assertEquals(10, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
80     }
81
82     @Test
83     public void testBEVImperialUnits() {
84         Thing thingMock = mock(Thing.class);
85         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
86         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
87         MercedesMeDynamicStateDescriptionProviderMock<?> patternMock = new MercedesMeDynamicStateDescriptionProviderMock<>(
88                 mock(EventPublisher.class), mock(ItemChannelLinkRegistry.class),
89                 mock(ChannelTypeI18nLocalizationService.class));
90         MercedesMeCommandOptionProviderMock commandOptionMock = new MercedesMeCommandOptionProviderMock();
91         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(), commandOptionMock, patternMock);
92
93         AccountHandlerMock ahm = new AccountHandlerMock();
94         vh.accountHandler = Optional.of(ahm);
95         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
96         vh.config = Optional.of(vehicleConfig);
97         ThingCallbackListener updateListener = new ThingCallbackListener();
98         vh.setCallback(updateListener);
99
100         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-ImperialUnits.json");
101         VEPUpdate update = ProtoConverter.json2Proto(json, true);
102         vh.distributeContent(update);
103
104         assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
105         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
106         assertEquals(5, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
107         assertEquals(8, updateListener.getUpdatesForGroup("windows"), "Windows Update Count");
108         assertEquals(12, updateListener.getUpdatesForGroup("trip"), "Trip Update Count");
109         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Tire Update Count");
110         assertEquals(6, updateListener.getUpdatesForGroup("service"), "Service Update Count");
111         assertEquals(7, updateListener.getUpdatesForGroup("range"), "Range Update Count");
112         assertEquals(2, updateListener.getUpdatesForGroup("position"), "Position Update Count");
113         assertEquals(5, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
114         assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
115         assertEquals(10, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
116         assertTrue(updateListener.getResponse("test::bev:range#mileage").toFullString().endsWith("mi"),
117                 "Mileague Unit");
118         assertTrue(updateListener.getResponse("test::bev:range#range-electric").toFullString().endsWith("mi"),
119                 "Range Electric Unit");
120         assertTrue(updateListener.getResponse("test::bev:trip#distance").toFullString().endsWith("mi"),
121                 "Range Electric Unit");
122         assertTrue(updateListener.getResponse("test::bev:tires#pressure-front-left").toFullString().endsWith("psi"),
123                 "Pressure Unit");
124         assertTrue(updateListener.getResponse("test::bev:hvac#temperature").toFullString().endsWith("°F"),
125                 "Temperature Unit");
126         assertEquals("%.0f °F", patternMock.patternMap.get("test::bev:hvac#temperature"), "Temperature Pattern");
127         commandOptionMock.getCommandList("test::bev:hvac#temperature").forEach(cmd -> {
128             assertTrue(cmd.getCommand().endsWith(" °F"), "Command Option Fahrenheit Unit");
129         });
130
131         // overwrite with EU Units
132         json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-EQA.json");
133         update = ProtoConverter.json2Proto(json, true);
134         vh.distributeContent(update);
135         assertEquals("%.1f °C", patternMock.patternMap.get("test::bev:hvac#temperature"), "Temperature Pattern");
136         commandOptionMock.getCommandList("test::bev:hvac#temperature").forEach(cmd -> {
137             assertTrue(cmd.getCommand().endsWith(" °C"), "Command Option Celsius Unit");
138         });
139     }
140
141     @Test
142     public void testBEVCharging() {
143         Thing thingMock = mock(Thing.class);
144         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
145         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
146         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
147                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
148         vh.accountHandler = Optional.of(mock(AccountHandler.class));
149         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
150         vh.config = Optional.of(vehicleConfig);
151         ThingCallbackListener updateListener = new ThingCallbackListener();
152         vh.setCallback(updateListener);
153
154         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-EQA-Charging.json");
155         VEPUpdate update = ProtoConverter.json2Proto(json, true);
156         vh.distributeContent(update);
157
158         assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
159         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
160         assertEquals(5, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
161         assertEquals(8, updateListener.getUpdatesForGroup("windows"), "Windows Update Count");
162         assertEquals(12, updateListener.getUpdatesForGroup("trip"), "Trip Update Count");
163         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Tire Update Count");
164         assertEquals(6, updateListener.getUpdatesForGroup("service"), "Service Update Count");
165         assertEquals(7, updateListener.getUpdatesForGroup("range"), "Range Update Count");
166         assertEquals(2, updateListener.getUpdatesForGroup("position"), "Position Update Count");
167         assertEquals(5, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
168         assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
169         assertEquals(10, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
170         assertEquals("2023-09-06 13:55", ((DateTimeType) updateListener.getResponse("test::bev:charge#end-time"))
171                 .format("%1$tY-%1$tm-%1$td %1$tH:%1$tM"), "End of Charge Time");
172     }
173
174     @Test
175     public void testBEVPartialChargingUpdate() {
176         Thing thingMock = mock(Thing.class);
177         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
178         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
179         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
180                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
181         vh.accountHandler = Optional.of(mock(AccountHandler.class));
182         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
183         vh.config = Optional.of(vehicleConfig);
184         ThingCallbackListener updateListener = new ThingCallbackListener();
185         vh.setCallback(updateListener);
186
187         String json = FileReader.readFileInString("src/test/resources/proto-json/PartialUpdate-Charging.json");
188         VEPUpdate update = ProtoConverter.json2Proto(json, false);
189         vh.distributeContent(update);
190         assertEquals(2, updateListener.updatesReceived.size(), "Update Count");
191         assertEquals("2023-09-19 20:45", ((DateTimeType) updateListener.getResponse("test::bev:charge#end-time"))
192                 .format("%1$tY-%1$tm-%1$td %1$tH:%1$tM"), "End of Charge Time");
193         assertEquals("2.1 kW", updateListener.getResponse("test::bev:charge#power").toFullString(), "Charge Power");
194     }
195
196     @Test
197     public void testBEVPartialGPSUpdate() {
198         Thing thingMock = mock(Thing.class);
199         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
200         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
201         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
202                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
203         vh.accountHandler = Optional.of(mock(AccountHandler.class));
204         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
205         vh.config = Optional.of(vehicleConfig);
206         ThingCallbackListener updateListener = new ThingCallbackListener();
207         vh.setCallback(updateListener);
208
209         String json = FileReader.readFileInString("src/test/resources/proto-json/PartialUpdate-GPS.json");
210         VEPUpdate update = ProtoConverter.json2Proto(json, false);
211         vh.distributeContent(update);
212         assertEquals(3, updateListener.updatesReceived.size(), "Update Count");
213         assertEquals("1.23,4.56", updateListener.getResponse("test::bev:position#gps").toFullString(), "GPS update");
214         assertEquals("41.9 °", updateListener.getResponse("test::bev:position#heading").toFullString(),
215                 "Heading Update");
216     }
217
218     @Test
219     public void testBEVPartialRangeUpdate() {
220         Thing thingMock = mock(Thing.class);
221         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
222         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
223         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
224                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
225         vh.accountHandler = Optional.of(mock(AccountHandler.class));
226         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
227         vh.config = Optional.of(vehicleConfig);
228         ThingCallbackListener updateListener = new ThingCallbackListener();
229         vh.setCallback(updateListener);
230
231         String json = FileReader.readFileInString("src/test/resources/proto-json/PartialUpdate-Range.json");
232         VEPUpdate update = ProtoConverter.json2Proto(json, false);
233         vh.distributeContent(update);
234         assertEquals(3, updateListener.updatesReceived.size(), "Update Count");
235         assertEquals("15017 km", updateListener.getResponse("test::bev:range#mileage").toFullString(),
236                 "Mileage Update");
237         assertEquals("246 km", updateListener.getResponse("test::bev:range#radius-electric").toFullString(),
238                 "Range Update");
239         assertEquals("307 km", updateListener.getResponse("test::bev:range#range-electric").toFullString(),
240                 "Range Radius Update");
241     }
242
243     @Test
244     public void testHybridFullUpdateNoCapacities() {
245         Thing thingMock = mock(Thing.class);
246         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_HYBRID);
247         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.HYBRID));
248         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
249                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
250         vh.accountHandler = Optional.of(mock(AccountHandler.class));
251         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
252         vh.config = Optional.of(vehicleConfig);
253         ThingCallbackListener updateListener = new ThingCallbackListener();
254         vh.setCallback(updateListener);
255
256         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-Hybrid-Charging.json");
257         VEPUpdate update = ProtoConverter.json2Proto(json, true);
258         vh.distributeContent(update);
259
260         assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
261         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
262         assertEquals(5, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
263         assertEquals(8, updateListener.getUpdatesForGroup("windows"), "Windows Update Count");
264         assertEquals(12, updateListener.getUpdatesForGroup("trip"), "Trip Update Count");
265         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Trip Update Count");
266         assertEquals(8, updateListener.getUpdatesForGroup("service"), "Trip Update Count");
267         assertEquals(14, updateListener.getUpdatesForGroup("range"), "Update Upadte Count");
268         assertEquals(2, updateListener.getUpdatesForGroup("position"), "Update Upadte Count");
269         assertEquals(6, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
270         assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
271         assertEquals(7, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
272     }
273
274     @Test
275     public void testHybridFullUpadteWithCapacities() {
276         Thing thingMock = mock(Thing.class);
277         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_HYBRID);
278         when(thingMock.getUID()).thenReturn(new ThingUID("test", "hybrid"));
279         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
280                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
281         vh.accountHandler = Optional.of(mock(AccountHandler.class));
282         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
283         vehicleConfig.batteryCapacity = (float) 9.2;
284         vehicleConfig.fuelCapacity = (float) 59.9;
285         vh.config = Optional.of(vehicleConfig);
286         ThingCallbackListener updateListener = new ThingCallbackListener();
287         vh.setCallback(updateListener);
288
289         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-Hybrid-Charging.json");
290         VEPUpdate update = ProtoConverter.json2Proto(json, true);
291         vh.distributeContent(update);
292
293         // Test charged / uncharged battery and filled / unfilled tank volume
294         assertEquals("5.800000190734863 kWh", updateListener.getResponse("test::hybrid:range#charged").toFullString(),
295                 "Battery Charged Update");
296         assertEquals("3.4000000953674316 kWh",
297                 updateListener.getResponse("test::hybrid:range#uncharged").toFullString(), "Battery Uncharged Update");
298         assertEquals("9.579999923706055 l", updateListener.getResponse("test::hybrid:range#tank-remain").toFullString(),
299                 "Tank Remain Update");
300         assertEquals("50.31999969482422 l", updateListener.getResponse("test::hybrid:range#tank-open").toFullString(),
301                 "Tank Open Update");
302     }
303
304     @Test
305     public void testEventStorage() {
306         Thing thingMock = mock(Thing.class);
307         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
308         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
309         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
310                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
311         vh.accountHandler = Optional.of(mock(AccountHandler.class));
312         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
313         vh.config = Optional.of(vehicleConfig);
314         ThingCallbackListener updateListener = new ThingCallbackListener();
315         updateListener.linked = true;
316         vh.setCallback(updateListener);
317
318         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-EQA.json");
319         VEPUpdate update = ProtoConverter.json2Proto(json, true);
320         vh.distributeContent(update);
321
322         assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
323         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
324         // 1 update more due to proto channel connected
325         // assertEquals(6, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
326         assertEquals(8, updateListener.getUpdatesForGroup("windows"), "Windows Update Count");
327         assertEquals(12, updateListener.getUpdatesForGroup("trip"), "Trip Update Count");
328         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Tire Update Count");
329         assertEquals(6, updateListener.getUpdatesForGroup("service"), "Service Update Count");
330         assertEquals(7, updateListener.getUpdatesForGroup("range"), "Range Update Count");
331         assertEquals(2, updateListener.getUpdatesForGroup("position"), "Position Update Count");
332         assertEquals(5, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
333         assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
334         assertEquals(10, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
335
336         /**
337          * VehicleHandler fully updated eventStorage shall contain all data
338          * Let's simulate an item ad causing a RefreshType command
339          * Shall deliver data immediately
340          */
341         assertEquals(83, vh.eventStorage.size());
342         assertEquals(83, updateListener.updatesReceived.size());
343         updateListener = new ThingCallbackListener();
344         vh.setCallback(updateListener);
345         ChannelUID mileageChannelUID = new ChannelUID(new ThingUID("test", Constants.BEV), Constants.GROUP_RANGE,
346                 "mileage");
347
348         vh.handleCommand(mileageChannelUID, RefreshType.REFRESH);
349         assertEquals(1, updateListener.updatesReceived.size());
350     }
351
352     @Test
353     public void testProtoChannelLinked() {
354         Thing thingMock = mock(Thing.class);
355         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
356         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
357         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
358                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
359         vh.accountHandler = Optional.of(mock(AccountHandler.class));
360         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
361         vh.config = Optional.of(vehicleConfig);
362         ThingCallbackListener updateListener = new ThingCallbackListener();
363         vh.setCallback(updateListener);
364
365         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-EQA.json");
366         VEPUpdate update = ProtoConverter.json2Proto(json, true);
367         vh.distributeContent(update);
368         assertFalse(updateListener.updatesReceived.containsKey("test::bev:vehicle#proto-update"),
369                 "Proto Channel not updated");
370
371         updateListener.linked = true;
372         vh.distributeContent(update);
373         assertTrue(updateListener.updatesReceived.containsKey("test::bev:vehicle#proto-update"),
374                 "Proto Channel not updated");
375     }
376
377     @Test
378     public void testTemperaturePoints() {
379         Thing thingMock = mock(Thing.class);
380         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
381         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
382         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
383                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
384         vh.accountHandler = Optional.of(mock(AccountHandler.class));
385         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
386         vh.config = Optional.of(vehicleConfig);
387         AccountHandlerMock ahm = new AccountHandlerMock();
388         vh.accountHandler = Optional.of(ahm);
389         ThingCallbackListener updateListener = new ThingCallbackListener();
390         vh.setCallback(updateListener);
391
392         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-Unknown.json");
393         VEPUpdate update = ProtoConverter.json2Proto(json, true);
394         vh.distributeContent(update);
395         assertEquals("22 °C", updateListener.getResponse("test::bev:hvac#temperature").toFullString(),
396                 "Temperature Point One Updated");
397
398         ChannelUID cuid = new ChannelUID(thingMock.getUID(), Constants.GROUP_HVAC, "zone");
399         updateListener = new ThingCallbackListener();
400         vh.setCallback(updateListener);
401         vh.handleCommand(cuid, new DecimalType(2));
402         assertEquals("2", updateListener.getResponse("test::bev:hvac#zone").toFullString(),
403                 "Temperature Point One Updated");
404         assertEquals("19 °C", updateListener.getResponse("test::bev:hvac#temperature").toFullString(),
405                 "Temperature Point One Updated");
406         vh.handleCommand(cuid, new DecimalType(-1));
407     }
408
409     @Test
410     public void testTemperaturePointSelection() {
411         Thing thingMock = mock(Thing.class);
412         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
413         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
414         when(thingMock.getProperties()).thenReturn(Map.of(MB_KEY_COMMAND_ZEV_PRECONDITION_CONFIGURE, "true"));
415         AccountHandlerMock ahm = new AccountHandlerMock();
416         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
417                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
418         vh.accountHandler = Optional.of(ahm);
419         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
420         vh.config = Optional.of(vehicleConfig);
421         ThingCallbackListener updateListener = new ThingCallbackListener();
422         vh.setCallback(updateListener);
423         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-Unknown.json");
424         VEPUpdate update = ProtoConverter.json2Proto(json, true);
425         vh.distributeContent(update);
426
427         ChannelUID cuid = new ChannelUID(thingMock.getUID(), Constants.GROUP_HVAC, "temperature");
428         updateListener = new ThingCallbackListener();
429         vh.setCallback(updateListener);
430         vh.handleCommand(cuid, QuantityType.valueOf("18 °C"));
431         assertEquals("frontLeft", ahm.getCommand().get("zone").toString(), "Zone Selection");
432         assertEquals(18, ahm.getCommand().getDouble("temperature_in_celsius"), "Temperature Selection");
433         vh.handleCommand(cuid, QuantityType.valueOf("80 °F"));
434         assertEquals("frontLeft", ahm.getCommand().get("zone").toString(), "Zone Selection");
435         assertEquals(26, ahm.getCommand().getDouble("temperature_in_celsius"), "Temperature Selection");
436     }
437
438     @Test
439     public void testChargeProgramSelection() {
440         Thing thingMock = mock(Thing.class);
441         when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
442         when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
443         when(thingMock.getProperties()).thenReturn(Map.of(MB_KEY_COMMAND_CHARGE_PROGRAM_CONFIGURE, "true"));
444         AccountHandlerMock ahm = new AccountHandlerMock();
445         VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
446                 mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
447         vh.accountHandler = Optional.of(ahm);
448         VehicleConfiguration vehicleConfig = new VehicleConfiguration();
449         vh.config = Optional.of(vehicleConfig);
450         ThingCallbackListener updateListener = new ThingCallbackListener();
451         vh.setCallback(updateListener);
452
453         String json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-EQA.json");
454         VEPUpdate update = ProtoConverter.json2Proto(json, true);
455         vh.distributeContent(update);
456
457         ChannelUID cuid = new ChannelUID(thingMock.getUID(), Constants.GROUP_CHARGE, "max-soc");
458         vh.handleCommand(cuid, QuantityType.valueOf("90 %"));
459         int selectedChargeProgram = ((DecimalType) updateListener.getResponse("test::bev:charge#program")).intValue();
460         assertEquals(selectedChargeProgram,
461                 Utils.getChargeProgramNumber(ahm.getCommand().get("charge_program").toString()),
462                 "Charge Program Command");
463         assertEquals(90, ahm.getCommand().getInt("max_soc"), "Charge Program SOC Setting");
464
465         cuid = new ChannelUID(thingMock.getUID(), Constants.GROUP_CHARGE, "program");
466         vh.handleCommand(cuid, new DecimalType(3));
467         assertEquals(3, Utils.getChargeProgramNumber(ahm.getCommand().get("charge_program").toString()),
468                 "Charge Program Command");
469         assertEquals(100, ahm.getCommand().getInt("max_soc"), "Charge Program SOC Setting");
470     }
471 }