]> git.basschouten.com Git - openhab-addons.git/blob
acd54c5478fb50544ac93b727c856435220db33d
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.bmwconnecteddrive.internal.dto;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*;
17
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21
22 import javax.measure.Unit;
23 import javax.measure.quantity.Length;
24 import javax.measure.quantity.Time;
25
26 import org.eclipse.jdt.annotation.NonNullByDefault;
27 import org.eclipse.jdt.annotation.Nullable;
28 import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType;
29 import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Doors;
30 import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus;
31 import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer;
32 import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows;
33 import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants;
34 import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter;
35 import org.openhab.binding.bmwconnecteddrive.internal.utils.VehicleStatusUtils;
36 import org.openhab.core.library.types.DateTimeType;
37 import org.openhab.core.library.types.PointType;
38 import org.openhab.core.library.types.QuantityType;
39 import org.openhab.core.library.types.StringType;
40 import org.openhab.core.library.unit.ImperialUnits;
41 import org.openhab.core.library.unit.Units;
42 import org.openhab.core.thing.ChannelUID;
43 import org.openhab.core.types.State;
44 import org.openhab.core.types.UnDefType;
45
46 import com.google.gson.Gson;
47
48 /**
49  * The {@link StatusWrapper} Test json responses from ConnectedDrive Portal
50  *
51  * @author Bernd Weymann - Initial contribution
52  */
53 @NonNullByDefault
54 @SuppressWarnings("null")
55 public class StatusWrapper {
56     private static final Gson GSON = new Gson();
57     private static final Unit<Length> KILOMETRE = Constants.KILOMETRE_UNIT;
58     private static final double ALLOWED_MILE_CONVERSION_DEVIATION = 1.5;
59     private static final double ALLOWED_KM_ROUND_DEVIATION = 0.1;
60
61     private VehicleStatus vStatus;
62     private boolean imperial;
63     private boolean isElectric;
64     private boolean hasFuel;
65     private boolean isHybrid;
66
67     private Map<String, State> specialHandlingMap = new HashMap<String, State>();
68
69     public StatusWrapper(String type, boolean imperial, String statusJson) {
70         this.imperial = imperial;
71         hasFuel = type.equals(VehicleType.CONVENTIONAL.toString()) || type.equals(VehicleType.PLUGIN_HYBRID.toString())
72                 || type.equals(VehicleType.ELECTRIC_REX.toString());
73         isElectric = type.equals(VehicleType.PLUGIN_HYBRID.toString())
74                 || type.equals(VehicleType.ELECTRIC_REX.toString()) || type.equals(VehicleType.ELECTRIC.toString());
75         isHybrid = hasFuel && isElectric;
76         VehicleStatusContainer container = GSON.fromJson(statusJson, VehicleStatusContainer.class);
77         assertNotNull(container);
78         assertNotNull(container.vehicleStatus);
79         vStatus = container.vehicleStatus;
80     }
81
82     /**
83      * Test results auctomatically against json values
84      *
85      * @param channels
86      * @param states
87      * @return
88      */
89     public boolean checkResults(@Nullable List<ChannelUID> channels, @Nullable List<State> states) {
90         assertNotNull(channels);
91         assertNotNull(states);
92         assertTrue(channels.size() == states.size(), "Same list sizes");
93         for (int i = 0; i < channels.size(); i++) {
94             checkResult(channels.get(i), states.get(i));
95         }
96         return true;
97     }
98
99     /**
100      * Add a specific check for a value e.g. hard coded "Upcoming Service" in order to check the right ordering
101      *
102      * @param specialHand
103      * @return
104      */
105     public StatusWrapper append(Map<String, State> compareMap) {
106         specialHandlingMap.putAll(compareMap);
107         return this;
108     }
109
110     @SuppressWarnings({ "unchecked", "rawtypes" })
111     private void checkResult(ChannelUID channelUID, State state) {
112         String cUid = channelUID.getIdWithoutGroup();
113         String gUid = channelUID.getGroupId();
114         QuantityType<Length> qt;
115         QuantityType<Time> qtt;
116         StringType st;
117         StringType wanted;
118         DateTimeType dtt;
119         PointType pt;
120         switch (cUid) {
121             case MILEAGE:
122                 assertTrue(state instanceof QuantityType);
123                 qt = ((QuantityType) state);
124                 if (imperial) {
125                     assertEquals(ImperialUnits.MILE, qt.getUnit(), "Miles");
126                 } else {
127                     assertEquals(KILOMETRE, qt.getUnit(), "KM");
128                 }
129                 switch (gUid) {
130                     case CHANNEL_GROUP_RANGE:
131                         assertEquals(qt.intValue(), vStatus.mileage, "Mileage");
132                         break;
133                     case CHANNEL_GROUP_SERVICE:
134                         if (vStatus.cbsData.isEmpty()) {
135                             assertEquals(qt.intValue(), -1, "Service Mileage");
136                         } else {
137                             assertEquals(qt.intValue(), vStatus.cbsData.get(0).cbsRemainingMileage, "Service Mileage");
138                         }
139                         break;
140                     case CHANNEL_GROUP_CHECK_CONTROL:
141                         if (vStatus.checkControlMessages.isEmpty()) {
142                             assertEquals(qt.intValue(), -1, "CheckControl Mileage");
143                         } else {
144                             assertEquals(qt.intValue(), vStatus.checkControlMessages.get(0).ccmMileage,
145                                     "CheckControl Mileage");
146                         }
147                         break;
148                     default:
149                         assertFalse(true, "Channel " + channelUID + " " + state + " not found");
150                         break;
151                 }
152                 break;
153             case RANGE_ELECTRIC:
154                 assertTrue(isElectric, "Is Eelctric");
155                 assertTrue(state instanceof QuantityType);
156                 qt = ((QuantityType) state);
157                 if (imperial) {
158                     assertEquals(ImperialUnits.MILE, qt.getUnit(), "Miles");
159                     assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeElectricMls),
160                             ALLOWED_MILE_CONVERSION_DEVIATION, "Mileage");
161                 } else {
162                     assertEquals(KILOMETRE, qt.getUnit(), "KM");
163                     assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeElectric),
164                             ALLOWED_KM_ROUND_DEVIATION, "Mileage");
165                 }
166                 break;
167             case RANGE_FUEL:
168                 assertTrue(hasFuel, "Has Fuel");
169                 if (!(state instanceof UnDefType)) {
170                     assertTrue(state instanceof QuantityType);
171                     qt = ((QuantityType) state);
172                     if (imperial) {
173                         assertEquals(ImperialUnits.MILE, qt.getUnit(), "Miles");
174                         assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuelMls),
175                                 ALLOWED_MILE_CONVERSION_DEVIATION, "Mileage");
176                     } else {
177                         assertEquals(KILOMETRE, qt.getUnit(), "KM");
178                         assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuel),
179                                 ALLOWED_KM_ROUND_DEVIATION, "Mileage");
180                     }
181                 }
182                 break;
183             case RANGE_HYBRID:
184                 assertTrue(isHybrid, "Is Hybrid");
185                 assertTrue(state instanceof QuantityType);
186                 qt = ((QuantityType) state);
187                 if (imperial) {
188                     assertEquals(ImperialUnits.MILE, qt.getUnit(), "Miles");
189                     assertEquals(Converter.round(qt.floatValue()),
190                             Converter.round(vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls),
191                             ALLOWED_MILE_CONVERSION_DEVIATION, "Mileage");
192                 } else {
193                     assertEquals(KILOMETRE, qt.getUnit(), "KM");
194                     assertEquals(Converter.round(qt.floatValue()),
195                             Converter.round(vStatus.remainingRangeElectric + vStatus.remainingRangeFuel),
196                             ALLOWED_KM_ROUND_DEVIATION, "Mileage");
197                 }
198                 break;
199             case REMAINING_FUEL:
200                 assertTrue(hasFuel, "Has Fuel");
201                 assertTrue(state instanceof QuantityType);
202                 qt = ((QuantityType) state);
203                 assertEquals(Units.LITRE, qt.getUnit(), "Liter Unit");
204                 assertEquals(Converter.round(vStatus.remainingFuel), Converter.round(qt.floatValue()), 0.01,
205                         "Fuel Level");
206                 break;
207             case SOC:
208                 assertTrue(isElectric, "Is Eelctric");
209                 assertTrue(state instanceof QuantityType);
210                 qt = ((QuantityType) state);
211                 assertEquals(Units.PERCENT, qt.getUnit(), "Percent");
212                 assertEquals(Converter.round(vStatus.chargingLevelHv), Converter.round(qt.floatValue()), 0.01,
213                         "Charge Level");
214                 break;
215             case LOCK:
216                 assertTrue(state instanceof StringType);
217                 st = (StringType) state;
218                 assertEquals(Converter.toTitleCase(vStatus.doorLockState), st.toString(), "Vehicle locked");
219                 break;
220             case DOORS:
221                 assertTrue(state instanceof StringType);
222                 st = (StringType) state;
223                 Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class);
224                 if (doorState != null) {
225                     assertEquals(VehicleStatusUtils.checkClosed(doorState), st.toString(), "Doors Closed");
226                 } else {
227                     assertTrue(false);
228                 }
229
230                 break;
231             case WINDOWS:
232                 assertTrue(state instanceof StringType);
233                 st = (StringType) state;
234                 Windows windowState = GSON.fromJson(GSON.toJson(vStatus), Windows.class);
235                 if (windowState != null) {
236                     if (specialHandlingMap.containsKey(WINDOWS)) {
237                         assertEquals(specialHandlingMap.get(WINDOWS).toString(), st.toString(), "Windows");
238                     } else {
239                         assertEquals(VehicleStatusUtils.checkClosed(windowState), st.toString(), "Windows");
240                     }
241                 } else {
242                     assertTrue(false);
243                 }
244
245                 break;
246             case CHECK_CONTROL:
247                 assertTrue(state instanceof StringType);
248                 st = (StringType) state;
249                 if (specialHandlingMap.containsKey(CHECK_CONTROL)) {
250                     assertEquals(specialHandlingMap.get(CHECK_CONTROL).toString(), st.toString(), "Check Control");
251                 } else {
252                     assertEquals(Converter.toTitleCase(VehicleStatusUtils.checkControlActive(vStatus)), st.toString(),
253                             "Check Control");
254                 }
255                 break;
256             case CHARGE_STATUS:
257                 assertTrue(isElectric, "Is Electric");
258                 assertTrue(state instanceof StringType);
259                 st = (StringType) state;
260                 if (vStatus.chargingStatus.contentEquals(Constants.INVALID)) {
261                     assertEquals(Converter.toTitleCase(vStatus.lastChargingEndReason), st.toString(), "Charge Status");
262                 } else {
263                     assertEquals(Converter.toTitleCase(vStatus.chargingStatus), st.toString(), "Charge Status");
264                 }
265                 break;
266             case CHARGE_REMAINING:
267                 assertTrue(isElectric, "Is Electric");
268                 if (vStatus.chargingTimeRemaining == null) {
269                     assertTrue(state instanceof UnDefType, "expected UndefType");
270                 } else {
271                     assertTrue(state instanceof QuantityType);
272                     qtt = ((QuantityType) state);
273                     assertEquals(qtt.doubleValue(), vStatus.chargingTimeRemaining);
274                     assertEquals(Units.MINUTE, qtt.getUnit(), "Minutes");
275                 }
276                 break;
277             case LAST_UPDATE:
278                 assertTrue(state instanceof DateTimeType);
279                 dtt = (DateTimeType) state;
280                 DateTimeType expected = DateTimeType
281                         .valueOf(Converter.getLocalDateTime(VehicleStatusUtils.getUpdateTime(vStatus)));
282                 assertEquals(expected.toString(), dtt.toString(), "Last Update");
283                 break;
284             case GPS:
285                 assertTrue(state instanceof PointType);
286                 pt = (PointType) state;
287                 assertNotNull(vStatus.position);
288                 assertEquals(vStatus.position.getCoordinates(), pt.toString(), "Coordinates");
289                 break;
290             case HEADING:
291                 assertTrue(state instanceof QuantityType);
292                 qt = ((QuantityType) state);
293                 assertEquals(Units.DEGREE_ANGLE, qt.getUnit(), "Angle Unit");
294                 assertNotNull(vStatus.position);
295                 assertEquals(vStatus.position.heading, qt.intValue(), 0.01, "Heading");
296                 break;
297             case RANGE_RADIUS_ELECTRIC:
298                 assertTrue(state instanceof QuantityType);
299                 assertTrue(isElectric);
300                 qt = (QuantityType) state;
301                 if (imperial) {
302                     assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeElectricMls), qt.floatValue(), 1,
303                             "Range Radius Electric mi");
304                 } else {
305                     assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeElectric), qt.floatValue(), 0.1,
306                             "Range Radius Electric km");
307                 }
308                 break;
309             case RANGE_RADIUS_FUEL:
310                 assertTrue(state instanceof QuantityType);
311                 assertTrue(hasFuel);
312                 qt = (QuantityType) state;
313                 if (imperial) {
314                     assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeFuelMls), qt.floatValue(), 1,
315                             "Range Radius Fuel mi");
316                 } else {
317                     assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeFuel), qt.floatValue(), 0.1,
318                             "Range Radius Fuel km");
319                 }
320                 break;
321             case RANGE_RADIUS_HYBRID:
322                 assertTrue(state instanceof QuantityType);
323                 assertTrue(isHybrid);
324                 qt = (QuantityType) state;
325                 if (imperial) {
326                     assertEquals(
327                             Converter.guessRangeRadius(
328                                     vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls),
329                             qt.floatValue(), ALLOWED_MILE_CONVERSION_DEVIATION, "Range Radius Hybrid mi");
330                 } else {
331                     assertEquals(
332                             Converter.guessRangeRadius(vStatus.remainingRangeElectric + vStatus.remainingRangeFuel),
333                             qt.floatValue(), ALLOWED_KM_ROUND_DEVIATION, "Range Radius Hybrid km");
334                 }
335                 break;
336             case DOOR_DRIVER_FRONT:
337                 assertTrue(state instanceof StringType);
338                 st = (StringType) state;
339                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.doorDriverFront));
340                 assertEquals(wanted.toString(), st.toString(), "Door");
341                 break;
342             case DOOR_DRIVER_REAR:
343                 assertTrue(state instanceof StringType);
344                 st = (StringType) state;
345                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.doorDriverRear));
346                 assertEquals(wanted.toString(), st.toString(), "Door");
347                 break;
348             case DOOR_PASSENGER_FRONT:
349                 assertTrue(state instanceof StringType);
350                 st = (StringType) state;
351                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.doorPassengerFront));
352                 assertEquals(wanted.toString(), st.toString(), "Door");
353                 break;
354             case DOOR_PASSENGER_REAR:
355                 assertTrue(state instanceof StringType);
356                 st = (StringType) state;
357                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.doorPassengerRear));
358                 assertEquals(wanted.toString(), st.toString(), "Door");
359                 break;
360             case TRUNK:
361                 assertTrue(state instanceof StringType);
362                 st = (StringType) state;
363                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.trunk));
364                 assertEquals(wanted.toString(), st.toString(), "Door");
365                 break;
366             case HOOD:
367                 assertTrue(state instanceof StringType);
368                 st = (StringType) state;
369                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.hood));
370                 assertEquals(wanted.toString(), st.toString(), "Door");
371                 break;
372             case WINDOW_DOOR_DRIVER_FRONT:
373                 assertTrue(state instanceof StringType);
374                 st = (StringType) state;
375                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.windowDriverFront));
376                 assertEquals(wanted.toString(), st.toString(), "Window");
377                 break;
378             case WINDOW_DOOR_DRIVER_REAR:
379                 assertTrue(state instanceof StringType);
380                 st = (StringType) state;
381                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.windowDriverRear));
382                 assertEquals(wanted.toString(), st.toString(), "Window");
383                 break;
384             case WINDOW_DOOR_PASSENGER_FRONT:
385                 assertTrue(state instanceof StringType);
386                 st = (StringType) state;
387                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.windowPassengerFront));
388                 assertEquals(wanted.toString(), st.toString(), "Window");
389                 break;
390             case WINDOW_DOOR_PASSENGER_REAR:
391                 assertTrue(state instanceof StringType);
392                 st = (StringType) state;
393                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.windowPassengerRear));
394                 assertEquals(wanted.toString(), st.toString(), "Window");
395                 break;
396             case WINDOW_REAR:
397                 assertTrue(state instanceof StringType);
398                 st = (StringType) state;
399                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.rearWindow));
400                 assertEquals(wanted.toString(), st.toString(), "Window");
401                 break;
402             case SUNROOF:
403                 assertTrue(state instanceof StringType);
404                 st = (StringType) state;
405                 wanted = StringType.valueOf(Converter.toTitleCase(vStatus.sunroof));
406                 assertEquals(wanted.toString(), st.toString(), "Window");
407                 break;
408             case SERVICE_DATE:
409                 assertTrue(state instanceof DateTimeType);
410                 dtt = (DateTimeType) state;
411                 if (gUid.contentEquals(CHANNEL_GROUP_STATUS)) {
412                     if (specialHandlingMap.containsKey(SERVICE_DATE)) {
413                         assertEquals(specialHandlingMap.get(SERVICE_DATE).toString(), dtt.toString(), "Next Service");
414                     } else {
415                         String dueDateString = VehicleStatusUtils.getNextServiceDate(vStatus);
416                         DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString));
417                         assertEquals(expectedDTT.toString(), dtt.toString(), "Next Service");
418                     }
419                 } else if (gUid.equals(CHANNEL_GROUP_SERVICE)) {
420                     String dueDateString = vStatus.cbsData.get(0).getDueDate();
421                     DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString));
422                     assertEquals(expectedDTT.toString(), dtt.toString(), "First Service Date");
423                 }
424                 break;
425             case SERVICE_MILEAGE:
426                 assertTrue(state instanceof QuantityType);
427                 qt = ((QuantityType) state);
428                 if (gUid.contentEquals(CHANNEL_GROUP_STATUS)) {
429                     if (imperial) {
430                         assertEquals(ImperialUnits.MILE, qt.getUnit(), "Next Service Miles");
431                         assertEquals(VehicleStatusUtils.getNextServiceMileage(vStatus), qt.intValue(), "Mileage");
432                     } else {
433                         assertEquals(KILOMETRE, qt.getUnit(), "Next Service KM");
434                         assertEquals(VehicleStatusUtils.getNextServiceMileage(vStatus), qt.intValue(), "Mileage");
435                     }
436                 } else if (gUid.equals(CHANNEL_GROUP_SERVICE)) {
437                     if (imperial) {
438                         assertEquals(ImperialUnits.MILE, qt.getUnit(), "First Service Miles");
439                         assertEquals(vStatus.cbsData.get(0).cbsRemainingMileage, qt.intValue(),
440                                 "First Service Mileage");
441                     } else {
442                         assertEquals(KILOMETRE, qt.getUnit(), "First Service KM");
443                         assertEquals(vStatus.cbsData.get(0).cbsRemainingMileage, qt.intValue(),
444                                 "First Service Mileage");
445                     }
446                 }
447                 break;
448             case NAME:
449                 assertTrue(state instanceof StringType);
450                 st = (StringType) state;
451                 switch (gUid) {
452                     case CHANNEL_GROUP_SERVICE:
453                         wanted = StringType.valueOf(Converter.toTitleCase(Constants.NO_ENTRIES));
454                         if (!vStatus.cbsData.isEmpty()) {
455                             wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getType()));
456                         }
457                         assertEquals(wanted.toString(), st.toString(), "Service Name");
458                         break;
459                     case CHANNEL_GROUP_CHECK_CONTROL:
460                         wanted = StringType.valueOf(Constants.NO_ENTRIES);
461                         if (!vStatus.checkControlMessages.isEmpty()) {
462                             wanted = StringType.valueOf(vStatus.checkControlMessages.get(0).ccmDescriptionShort);
463                         }
464                         assertEquals(wanted.toString(), st.toString(), "CheckControl Name");
465                         break;
466                     default:
467                         assertFalse(true, "Channel " + channelUID + " " + state + " not found");
468                         break;
469                 }
470                 break;
471             case DETAILS:
472                 assertTrue(state instanceof StringType);
473                 st = (StringType) state;
474                 switch (gUid) {
475                     case CHANNEL_GROUP_SERVICE:
476                         wanted = StringType.valueOf(Converter.toTitleCase(Constants.NO_ENTRIES));
477                         if (!vStatus.cbsData.isEmpty()) {
478                             wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getDescription()));
479                         }
480                         assertEquals(wanted.toString(), st.toString(), "Service Details");
481                         break;
482                     case CHANNEL_GROUP_CHECK_CONTROL:
483                         wanted = StringType.valueOf(Constants.NO_ENTRIES);
484                         if (!vStatus.checkControlMessages.isEmpty()) {
485                             wanted = StringType.valueOf(vStatus.checkControlMessages.get(0).ccmDescriptionLong);
486                         }
487                         assertEquals(wanted.toString(), st.toString(), "CheckControl Details");
488                         break;
489                     default:
490                         assertFalse(true, "Channel " + channelUID + " " + state + " not found");
491                         break;
492                 }
493                 break;
494             case DATE:
495                 assertTrue(state instanceof DateTimeType);
496                 dtt = (DateTimeType) state;
497                 switch (gUid) {
498                     case CHANNEL_GROUP_SERVICE:
499                         String dueDateString = Constants.NULL_DATE;
500                         if (!vStatus.cbsData.isEmpty()) {
501                             dueDateString = vStatus.cbsData.get(0).getDueDate();
502                         }
503                         DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString));
504                         assertEquals(expectedDTT.toString(), dtt.toString(), "ServiceSate");
505                         break;
506                     default:
507                         assertFalse(true, "Channel " + channelUID + " " + state + " not found");
508                         break;
509                 }
510                 break;
511             default:
512                 // fail in case of unknown update
513                 assertFalse(true, "Channel " + channelUID + " " + state + " not found");
514                 break;
515         }
516     }
517 }