]> git.basschouten.com Git - openhab-addons.git/blob
c12f5b9fa8c86743cd25c821f4c260f59b46c9a9
[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.utils;
14
15 import static org.openhab.binding.mercedesme.internal.Constants.*;
16
17 import java.time.Instant;
18 import java.time.temporal.ChronoUnit;
19 import java.util.HashMap;
20 import java.util.Locale;
21 import java.util.Map;
22
23 import javax.measure.Unit;
24 import javax.measure.quantity.Length;
25 import javax.measure.quantity.Pressure;
26 import javax.measure.quantity.Speed;
27 import javax.measure.quantity.Temperature;
28 import javax.measure.quantity.Volume;
29
30 import org.eclipse.jdt.annotation.NonNullByDefault;
31 import org.openhab.core.i18n.UnitProvider;
32 import org.openhab.core.library.types.DecimalType;
33 import org.openhab.core.library.types.OnOffType;
34 import org.openhab.core.library.types.OpenClosedType;
35 import org.openhab.core.library.types.QuantityType;
36 import org.openhab.core.library.types.StringType;
37 import org.openhab.core.library.unit.ImperialUnits;
38 import org.openhab.core.library.unit.SIUnits;
39 import org.openhab.core.library.unit.Units;
40 import org.openhab.core.types.State;
41 import org.openhab.core.types.UnDefType;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import com.daimler.mbcarkit.proto.VehicleEvents.VehicleAttributeStatus;
46
47 /**
48  * {@link Mapper} converts Mercedes keys to channel name and group and converts delivered vehicle data
49  *
50  * @author Bernd Weymann - Initial contribution
51  */
52 @NonNullByDefault
53 public class Mapper {
54     private static final Logger LOGGER = LoggerFactory.getLogger(Mapper.class);
55
56     public static final ChannelStateMap INVALID_MAP = new ChannelStateMap(EMPTY, EMPTY, UnDefType.UNDEF);
57     public static final Map<String, String[]> CHANNELS = new HashMap<>();
58     public static final String TIMESTAMP = "timestamp";
59     public static final String VALUE = "value";
60
61     public static Unit<Length> defaultLengthUnit = KILOMETRE_UNIT;
62     public static Unit<Temperature> defaultTemperatureUnit = SIUnits.CELSIUS;
63     public static Unit<Pressure> defaultPressureUnit = Units.BAR;
64     public static Unit<Volume> defaultVolumeUnit = Units.LITRE;
65     public static Unit<Speed> defaultSpeedUnit = SIUnits.KILOMETRE_PER_HOUR;
66
67     public static void initialize(UnitProvider up) {
68         // Configure Mapper default values
69         Unit<Length> lengthUnit = up.getUnit(Length.class);
70         if (ImperialUnits.FOOT.equals(lengthUnit)) {
71             defaultLengthUnit = ImperialUnits.MILE;
72             defaultSpeedUnit = ImperialUnits.MILES_PER_HOUR;
73             defaultPressureUnit = ImperialUnits.POUND_FORCE_SQUARE_INCH;
74             defaultVolumeUnit = ImperialUnits.GALLON_LIQUID_US;
75         }
76         Unit<Temperature> temperatureUnit = up.getUnit(Temperature.class);
77         defaultTemperatureUnit = temperatureUnit;
78     }
79
80     public static ChannelStateMap getChannelStateMap(String key, VehicleAttributeStatus value) {
81         if (CHANNELS.isEmpty()) {
82             init();
83         }
84         String[] ch = CHANNELS.get(key);
85         if (ch != null) {
86             State state;
87             UOMObserver observer = null;
88             switch (key) {
89                 // Kilometer values
90                 case MB_KEY_ODO:
91                 case MB_KEY_RANGEELECTRIC:
92                 case MB_KEY_OVERALL_RANGE:
93                 case MB_KEY_RANGELIQUID:
94                 case MB_KEY_DISTANCE_START:
95                 case MB_KEY_DISTANCE_RESET:
96                     Unit<?> lengthUnit = defaultLengthUnit;
97                     if (value.hasDistanceUnit()) {
98                         observer = new UOMObserver(value.getDistanceUnit().toString());
99                         Unit<?> queryUnit = observer.getUnit();
100                         if (queryUnit != null) {
101                             lengthUnit = queryUnit;
102                         } else {
103                             LOGGER.trace("No Unit found for {} - take default ", key);
104                         }
105                     }
106                     state = QuantityType.valueOf(Utils.getDouble(value), lengthUnit);
107                     return new ChannelStateMap(ch[0], ch[1], state, observer);
108
109                 // special String Value
110                 case MB_KEY_DRIVEN_TIME_START:
111                 case MB_KEY_DRIVEN_TIME_RESET:
112                     int duration = Utils.getInt(value);
113                     if (duration < 0) {
114                         state = UnDefType.UNDEF;
115                     } else {
116                         state = StringType.valueOf(Utils.getDurationString(duration));
117                     }
118                     return new ChannelStateMap(ch[0], ch[1], state);
119
120                 // KiloWatt values
121                 case MB_KEY_CHARGING_POWER:
122                     double power = Utils.getDouble(value);
123                     state = QuantityType.valueOf(Math.max(0, power), KILOWATT_UNIT);
124                     return new ChannelStateMap(ch[0], ch[1], state);
125
126                 case MB_KEY_AVERAGE_SPEED_START:
127                 case MB_KEY_AVERAGE_SPEED_RESET:
128                     Unit<?> speedUnit = defaultSpeedUnit;
129                     if (value.hasSpeedUnit()) {
130                         observer = new UOMObserver(value.getSpeedUnit().toString());
131                         Unit<?> queryUnit = observer.getUnit();
132                         if (queryUnit != null) {
133                             lengthUnit = observer.getUnit();
134                         } else {
135                             LOGGER.trace("No Unit found for {} - take default ", key);
136                         }
137                     }
138                     double speed = Utils.getDouble(value);
139                     state = QuantityType.valueOf(Math.max(0, speed), speedUnit);
140                     return new ChannelStateMap(ch[0], ch[1], state, observer);
141
142                 // KiloWatt/Hour values
143                 case MB_KEY_ELECTRICCONSUMPTIONSTART:
144                 case MB_KEY_ELECTRICCONSUMPTIONRESET:
145                     double consumptionEv = Utils.getDouble(value);
146                     state = new DecimalType(consumptionEv);
147                     if (value.hasElectricityConsumptionUnit()) {
148                         observer = new UOMObserver(value.getElectricityConsumptionUnit().toString());
149                     } else {
150                         LOGGER.trace("Don't have electric consumption unit for {}", key);
151                     }
152                     return new ChannelStateMap(ch[0], ch[1], state, observer);
153
154                 // Litre values
155                 case MB_KEY_LIQUIDCONSUMPTIONSTART:
156                 case MB_KEY_LIQUIDCONSUMPTIONRESET:
157                     double consumptionComb = Utils.getDouble(value);
158                     state = new DecimalType(consumptionComb);
159                     if (value.hasCombustionConsumptionUnit()) {
160                         observer = new UOMObserver(value.getCombustionConsumptionUnit().toString());
161                     }
162                     return new ChannelStateMap(ch[0], ch[1], state, observer);
163
164                 // Time - end of charging
165                 case MB_KEY_ENDOFCHARGETIME:
166                     if (Utils.isNil(value)) {
167                         state = UnDefType.UNDEF;
168                     } else {
169                         // int value is representing "minutes after Midnight!
170                         Instant time = Instant.ofEpochMilli(value.getTimestampInMs());
171                         long minutesAddon = Utils.getInt(value);
172                         time.plus(minutesAddon, ChronoUnit.MINUTES);
173                         state = Utils.getEndOfChargeTime(time.toEpochMilli(), minutesAddon);
174                         if (Locale.US.getCountry().equals(Utils.getCountry())) {
175                             observer = new UOMObserver(UOMObserver.TIME_US);
176                         } else {
177                             observer = new UOMObserver(UOMObserver.TIME_ROW);
178                         }
179                     }
180                     return new ChannelStateMap(ch[0], ch[1], state, observer);
181
182                 // DateTime - last Update
183                 case MB_KEY_TIRE_PRESS_MEAS_TIMESTAMP:
184                     if (Utils.isNil(value)) {
185                         state = UnDefType.UNDEF;
186                     } else {
187                         state = Utils.getDateTimeType(value.getTimestampInMs());
188                     }
189                     if (Locale.US.getCountry().equals(Utils.getCountry())) {
190                         observer = new UOMObserver(UOMObserver.TIME_US);
191                     } else {
192                         observer = new UOMObserver(UOMObserver.TIME_ROW);
193                     }
194                     return new ChannelStateMap(ch[0], ch[1], state, observer);
195
196                 // Percentages
197                 case MB_KEY_SOC:
198                 case MB_KEY_TANKLEVELPERCENT:
199                     double level = Utils.getDouble(value);
200                     state = QuantityType.valueOf(level, Units.PERCENT);
201                     return new ChannelStateMap(ch[0], ch[1], state);
202
203                 // Contacts
204                 case MB_KEY_DOORSTATUSFRONTRIGHT:
205                 case MB_KEY_DOORSTATUSFRONTLEFT:
206                 case MB_KEY_DOORSTATUSREARRIGHT:
207                 case MB_KEY_DOORSTATUSREARLEFT:
208                 case MB_KEY_DECKLIDSTATUS:
209                 case MB_KEY_ENGINE_HOOD_STATUS:
210                     if (Utils.isNil(value)) {
211                         state = UnDefType.UNDEF;
212                     } else {
213                         state = getContact(value.getBoolValue());
214                     }
215                     return new ChannelStateMap(ch[0], ch[1], state);
216
217                 // Number Status
218                 case MB_KEY_DOOR_LOCK_STATUS_OVERALL:
219                 case MB_KEY_WINDOW_STATUS_OVERALL:
220                 case MB_KEY_DOOR_STATUS_OVERALL:
221                 case MB_KEY_IGNITIONSTATE:
222                 case MB_KEY_SUNROOFSTATUS:
223                 case MB_KEY_SUNROOF_STATUS_FRONT_BLIND:
224                 case MB_KEY_SUNROOF_STATUS_REAR_BLIND:
225                 case MB_KEY_ROOFTOPSTATUS:
226                 case MB_KEY_WINDOWSTATUSFRONTLEFT:
227                 case MB_KEY_WINDOWSTATUSFRONTRIGHT:
228                 case MB_KEY_WINDOWSTATUSREARLEFT:
229                 case MB_KEY_WINDOWSTATUSREARRIGHT:
230                 case MB_KEY_WINDOW_STATUS_REAR_RIGHT_BLIND:
231                 case MB_KEY_WINDOW_STATUS_REAR_LEFT_BLIND:
232                 case MB_KEY_WINDOW_STATUS_REAR_BLIND:
233                 case MB_KEY_FLIP_WINDOW_STATUS:
234                 case MB_KEY_STARTER_BATTERY_STATE:
235                 case MB_KEY_TIREWARNINGSRDK:
236                 case MB_KEY_SERVICEINTERVALDAYS:
237                 case MB_KEY_CHARGE_FLAP_DC_STATUS:
238                 case MB_KEY_CHARGE_COUPLER_AC_STATUS:
239                 case MB_KEY_CHARGE_COUPLER_DC_STATUS:
240                 case MB_KEY_CHARGE_COUPLER_DC_LOCK_STATUS:
241                 case MB_KEY_TIRE_SENSOR_AVAILABLE:
242                     int stateNumberInteger = Utils.getInt(value);
243                     if (stateNumberInteger < 0) {
244                         state = UnDefType.UNDEF;
245                     } else {
246                         state = new DecimalType(stateNumberInteger);
247                     }
248                     return new ChannelStateMap(ch[0], ch[1], state);
249
250                 case MB_KEY_TIRE_MARKER_FRONT_RIGHT:
251                 case MB_KEY_TIRE_MARKER_FRONT_LEFT:
252                 case MB_KEY_TIRE_MARKER_REAR_RIGHT:
253                 case MB_KEY_TIRE_MARKER_REAR_LEFT:
254                     double stateNumberDouble = Utils.getDouble(value);
255                     if (stateNumberDouble < 0) {
256                         state = UnDefType.UNDEF;
257                     } else {
258                         state = new DecimalType(stateNumberDouble);
259                     }
260                     return new ChannelStateMap(ch[0], ch[1], state);
261
262                 // Switches
263                 case MB_KEY_PARKBRAKESTATUS:
264                 case MB_KEY_PRECOND_NOW:
265                 case MB_KEY_PRECOND_SEAT_FRONT_RIGHT:
266                 case MB_KEY_PRECOND_SEAT_FRONT_LEFT:
267                 case MB_KEY_PRECOND_SEAT_REAR_RIGHT:
268                 case MB_KEY_PRECOND_SEAT_REAR_LEFT:
269                 case MB_KEY_WARNINGBRAKEFLUID:
270                 case MB_KEY_WARNINGBRAKELININGWEAR:
271                 case MB_KEY_WARNINGWASHWATER:
272                 case MB_KEY_WARNINGCOOLANTLEVELLOW:
273                 case MB_KEY_WARNINGENGINELIGHT:
274                 case MB_KEY_CHARGINGACTIVE:
275                     if (Utils.isNil(value)) {
276                         state = UnDefType.UNDEF;
277                     } else {
278                         if (value.hasBoolValue()) {
279                             state = OnOffType.from(value.getBoolValue());
280                         } else {
281                             state = UnDefType.UNDEF;
282                         }
283                     }
284                     return new ChannelStateMap(ch[0], ch[1], state);
285
286                 // Switches - lock values with reversed boolean interpretation
287                 case MB_KEY_DOORLOCKSTATUSFRONTRIGHT:
288                 case MB_KEY_DOORLOCKSTATUSFRONTLEFT:
289                 case MB_KEY_DOORLOCKSTATUSREARRIGHT:
290                 case MB_KEY_DOORLOCKSTATUSREARLEFT:
291                 case MB_KEY_DOORLOCKSTATUSDECKLID:
292                 case MB_KEY_DOORLOCKSTATUSGAS:
293                     if (Utils.isNil(value)) {
294                         state = UnDefType.UNDEF;
295                     } else {
296                         // sad but true - false means locked
297                         state = OnOffType.from(!value.getBoolValue());
298                     }
299                     return new ChannelStateMap(ch[0], ch[1], state);
300
301                 // Angle
302                 case MB_KEY_POSITION_HEADING:
303                     double heading = Utils.getDouble(value);
304                     if (heading < 0) {
305                         state = UnDefType.UNDEF;
306                     } else {
307                         state = QuantityType.valueOf(heading, Units.DEGREE_ANGLE);
308                     }
309                     return new ChannelStateMap(ch[0], ch[1], state);
310
311                 // tires
312                 case MB_KEY_TIREPRESSURE_FRONT_LEFT:
313                 case MB_KEY_TIREPRESSURE_FRONT_RIGHT:
314                 case MB_KEY_TIREPRESSURE_REAR_LEFT:
315                 case MB_KEY_TIREPRESSURE_REAR_RIGHT:
316                     Unit<?> pressureUnit = defaultPressureUnit;
317                     if (value.hasPressureUnit()) {
318                         observer = new UOMObserver(value.getPressureUnit().toString());
319                         Unit<?> queryUnit = observer.getUnit();
320                         if (queryUnit != null) {
321                             pressureUnit = queryUnit;
322                         } else {
323                             LOGGER.trace("No Unit found for {} - take default ", key);
324                         }
325                     }
326                     double pressure = Utils.getDouble(value);
327                     state = QuantityType.valueOf(pressure, pressureUnit);
328                     return new ChannelStateMap(ch[0], ch[1], state, observer);
329                 default:
330                     break;
331             }
332         }
333         return INVALID_MAP;
334     }
335
336     private static State getContact(boolean b) {
337         if (!b) {
338             return OpenClosedType.CLOSED;
339         } else {
340             return OpenClosedType.OPEN;
341         }
342     }
343
344     /**
345      * Mapping of json id towards channel group and id
346      */
347     private static void init() {
348         CHANNELS.put(MB_KEY_DOOR_LOCK_STATUS_OVERALL, new String[] { OH_CHANNEL_LOCK, GROUP_VEHICLE });
349         CHANNELS.put(MB_KEY_WINDOW_STATUS_OVERALL, new String[] { OH_CHANNEL_WINDOWS, GROUP_VEHICLE });
350         CHANNELS.put(MB_KEY_DOOR_STATUS_OVERALL, new String[] { OH_CHANNEL_DOOR_STATUS, GROUP_VEHICLE });
351         CHANNELS.put(MB_KEY_IGNITIONSTATE, new String[] { OH_CHANNEL_IGNITION, GROUP_VEHICLE });
352         CHANNELS.put(MB_KEY_PARKBRAKESTATUS, new String[] { OH_CHANNEL_PARK_BRAKE, GROUP_VEHICLE });
353
354         CHANNELS.put(MB_KEY_DOORSTATUSFRONTRIGHT, new String[] { OH_CHANNEL_FRONT_RIGHT, GROUP_DOORS });
355         CHANNELS.put(MB_KEY_DOORSTATUSFRONTLEFT, new String[] { OH_CHANNEL_FRONT_LEFT, GROUP_DOORS });
356         CHANNELS.put(MB_KEY_DOORSTATUSREARRIGHT, new String[] { OH_CHANNEL_REAR_RIGHT, GROUP_DOORS });
357         CHANNELS.put(MB_KEY_DOORSTATUSREARLEFT, new String[] { OH_CHANNEL_REAR_LEFT, GROUP_DOORS });
358         CHANNELS.put(MB_KEY_DECKLIDSTATUS, new String[] { OH_CHANNEL_DECK_LID, GROUP_DOORS });
359         CHANNELS.put(MB_KEY_ENGINE_HOOD_STATUS, new String[] { OH_CHANNEL_ENGINE_HOOD, GROUP_DOORS });
360         CHANNELS.put(MB_KEY_SUNROOFSTATUS, new String[] { OH_CHANNEL_SUNROOF, GROUP_DOORS });
361         CHANNELS.put(MB_KEY_SUNROOF_STATUS_FRONT_BLIND, new String[] { OH_CHANNEL_SUNROOF_FRONT_BLIND, GROUP_DOORS });
362         CHANNELS.put(MB_KEY_SUNROOF_STATUS_REAR_BLIND, new String[] { OH_CHANNEL_SUNROOF_REAR_BLIND, GROUP_DOORS });
363         CHANNELS.put(MB_KEY_ROOFTOPSTATUS, new String[] { OH_CHANNEL_ROOFTOP, GROUP_DOORS });
364
365         CHANNELS.put(MB_KEY_DOORLOCKSTATUSFRONTRIGHT, new String[] { OH_CHANNEL_FRONT_RIGHT, GROUP_LOCK });
366         CHANNELS.put(MB_KEY_DOORLOCKSTATUSFRONTLEFT, new String[] { OH_CHANNEL_FRONT_LEFT, GROUP_LOCK });
367         CHANNELS.put(MB_KEY_DOORLOCKSTATUSREARRIGHT, new String[] { OH_CHANNEL_REAR_RIGHT, GROUP_LOCK });
368         CHANNELS.put(MB_KEY_DOORLOCKSTATUSREARLEFT, new String[] { OH_CHANNEL_REAR_LEFT, GROUP_LOCK });
369         CHANNELS.put(MB_KEY_DOORLOCKSTATUSDECKLID, new String[] { OH_CHANNEL_DECK_LID, GROUP_LOCK });
370         CHANNELS.put(MB_KEY_DOORLOCKSTATUSGAS, new String[] { OH_CHANNEL_GAS_FLAP, GROUP_LOCK });
371
372         CHANNELS.put(MB_KEY_WINDOWSTATUSFRONTLEFT, new String[] { OH_CHANNEL_FRONT_LEFT, GROUP_WINDOWS });
373         CHANNELS.put(MB_KEY_WINDOWSTATUSFRONTRIGHT, new String[] { OH_CHANNEL_FRONT_RIGHT, GROUP_WINDOWS });
374         CHANNELS.put(MB_KEY_WINDOWSTATUSREARLEFT, new String[] { OH_CHANNEL_REAR_LEFT, GROUP_WINDOWS });
375         CHANNELS.put(MB_KEY_WINDOWSTATUSREARRIGHT, new String[] { OH_CHANNEL_REAR_RIGHT, GROUP_WINDOWS });
376         CHANNELS.put(MB_KEY_WINDOW_STATUS_REAR_RIGHT_BLIND,
377                 new String[] { OH_CHANNEL_REAR_RIGHT_BLIND, GROUP_WINDOWS });
378         CHANNELS.put(MB_KEY_WINDOW_STATUS_REAR_LEFT_BLIND, new String[] { OH_CHANNEL_REAR_LEFT_BLIND, GROUP_WINDOWS });
379         CHANNELS.put(MB_KEY_WINDOW_STATUS_REAR_BLIND, new String[] { OH_CHANNEL_REAR_BLIND, GROUP_WINDOWS });
380         CHANNELS.put(MB_KEY_FLIP_WINDOW_STATUS, new String[] { OH_CHANNEL_FLIP_WINDOW, GROUP_WINDOWS });
381
382         CHANNELS.put(MB_KEY_PRECOND_NOW, new String[] { OH_CHANNEL_ACTIVE, GROUP_HVAC });
383         CHANNELS.put(MB_KEY_PRECOND_SEAT_FRONT_RIGHT, new String[] { OH_CHANNEL_FRONT_RIGHT, GROUP_HVAC });
384         CHANNELS.put(MB_KEY_PRECOND_SEAT_FRONT_LEFT, new String[] { OH_CHANNEL_FRONT_LEFT, GROUP_HVAC });
385         CHANNELS.put(MB_KEY_PRECOND_SEAT_REAR_RIGHT, new String[] { OH_CHANNEL_REAR_RIGHT, GROUP_HVAC });
386         CHANNELS.put(MB_KEY_PRECOND_SEAT_REAR_LEFT, new String[] { OH_CHANNEL_REAR_LEFT, GROUP_HVAC });
387         // temperaturePoints - special handling: sets zone & temperature
388
389         CHANNELS.put(MB_KEY_STARTER_BATTERY_STATE, new String[] { OH_CHANNEL_STARTER_BATTERY, GROUP_SERVICE });
390         CHANNELS.put(MB_KEY_WARNINGBRAKEFLUID, new String[] { OH_CHANNEL_BRAKE_FLUID, GROUP_SERVICE });
391         CHANNELS.put(MB_KEY_WARNINGWASHWATER, new String[] { OH_CHANNEL_WASH_WATER, GROUP_SERVICE });
392         CHANNELS.put(MB_KEY_WARNINGBRAKELININGWEAR, new String[] { OH_CHANNEL_BRAKE_LINING_WEAR, GROUP_SERVICE });
393         CHANNELS.put(MB_KEY_WARNINGCOOLANTLEVELLOW, new String[] { OH_CHANNEL_COOLANT_FLUID, GROUP_SERVICE });
394         CHANNELS.put(MB_KEY_WARNINGENGINELIGHT, new String[] { OH_CHANNEL_ENGINE, GROUP_SERVICE });
395         CHANNELS.put(MB_KEY_TIREWARNINGSRDK, new String[] { OH_CHANNEL_TIRES_RDK, GROUP_SERVICE });
396         CHANNELS.put(MB_KEY_SERVICEINTERVALDAYS, new String[] { OH_CHANNEL_SERVICE_DAYS, GROUP_SERVICE });
397
398         CHANNELS.put(MB_KEY_ODO, new String[] { OH_CHANNEL_MILEAGE, GROUP_RANGE });
399         CHANNELS.put(MB_KEY_RANGEELECTRIC, new String[] { OH_CHANNEL_RANGE_ELECTRIC, GROUP_RANGE });
400         CHANNELS.put(MB_KEY_SOC, new String[] { MB_KEY_SOC, GROUP_RANGE });
401         CHANNELS.put(MB_KEY_RANGELIQUID, new String[] { OH_CHANNEL_RANGE_FUEL, GROUP_RANGE });
402         CHANNELS.put(MB_KEY_OVERALL_RANGE, new String[] { OH_CHANNEL_RANGE_HYBRID, GROUP_RANGE });
403         CHANNELS.put(MB_KEY_TANKLEVELPERCENT, new String[] { OH_CHANNEL_FUEL_LEVEL, GROUP_RANGE });
404
405         CHANNELS.put(MB_KEY_CHARGE_FLAP_DC_STATUS, new String[] { OH_CHANNEL_CHARGE_FLAP, GROUP_CHARGE });
406         CHANNELS.put(MB_KEY_CHARGE_COUPLER_AC_STATUS, new String[] { OH_CHANNEL_COUPLER_AC, GROUP_CHARGE });
407         CHANNELS.put(MB_KEY_CHARGE_COUPLER_DC_STATUS, new String[] { OH_CHANNEL_COUPLER_DC, GROUP_CHARGE });
408         CHANNELS.put(MB_KEY_CHARGE_COUPLER_DC_LOCK_STATUS, new String[] { OH_CHANNEL_COUPLER_LOCK, GROUP_CHARGE });
409         CHANNELS.put(MB_KEY_CHARGINGACTIVE, new String[] { OH_CHANNEL_ACTIVE, GROUP_CHARGE });
410         CHANNELS.put(MB_KEY_CHARGING_POWER, new String[] { OH_CHANNEL_POWER, GROUP_CHARGE });
411         CHANNELS.put(MB_KEY_ENDOFCHARGETIME, new String[] { OH_CHANNEL_END_TIME, GROUP_CHARGE });
412
413         CHANNELS.put(MB_KEY_POSITION_HEADING, new String[] { OH_CHANNEL_HEADING, GROUP_POSITION });
414
415         CHANNELS.put(MB_KEY_DISTANCE_START, new String[] { OH_CHANNEL_DISTANCE, GROUP_TRIP });
416         CHANNELS.put(MB_KEY_DRIVEN_TIME_START, new String[] { OH_CHANNEL_TIME, GROUP_TRIP });
417         CHANNELS.put(MB_KEY_AVERAGE_SPEED_START, new String[] { OH_CHANNEL_AVG_SPEED, GROUP_TRIP });
418         CHANNELS.put(MB_KEY_ELECTRICCONSUMPTIONSTART, new String[] { OH_CHANNEL_CONS_EV, GROUP_TRIP });
419         CHANNELS.put(MB_KEY_LIQUIDCONSUMPTIONSTART, new String[] { OH_CHANNEL_CONS_CONV, GROUP_TRIP });
420         CHANNELS.put(MB_KEY_DISTANCE_RESET, new String[] { OH_CHANNEL_DISTANCE_RESET, GROUP_TRIP });
421         CHANNELS.put(MB_KEY_DRIVEN_TIME_RESET, new String[] { OH_CHANNEL_TIME_RESET, GROUP_TRIP });
422         CHANNELS.put(MB_KEY_AVERAGE_SPEED_RESET, new String[] { OH_CHANNEL_AVG_SPEED_RESET, GROUP_TRIP });
423         CHANNELS.put(MB_KEY_ELECTRICCONSUMPTIONRESET, new String[] { OH_CHANNEL_CONS_EV_RESET, GROUP_TRIP });
424         CHANNELS.put(MB_KEY_LIQUIDCONSUMPTIONRESET, new String[] { OH_CHANNEL_CONS_CONV_RESET, GROUP_TRIP });
425
426         CHANNELS.put(MB_KEY_TIREPRESSURE_REAR_RIGHT, new String[] { OH_CHANNEL_PRESSURE_REAR_RIGHT, GROUP_TIRES });
427         CHANNELS.put(MB_KEY_TIREPRESSURE_FRONT_RIGHT, new String[] { OH_CHANNEL_PRESSURE_FRONT_RIGHT, GROUP_TIRES });
428         CHANNELS.put(MB_KEY_TIREPRESSURE_REAR_LEFT, new String[] { OH_CHANNEL_PRESSURE_REAR_LEFT, GROUP_TIRES });
429         CHANNELS.put(MB_KEY_TIREPRESSURE_FRONT_LEFT, new String[] { OH_CHANNEL_PRESSURE_FRONT_LEFT, GROUP_TIRES });
430         CHANNELS.put(MB_KEY_TIRE_MARKER_FRONT_RIGHT, new String[] { OH_CHANNEL_MARKER_REAR_RIGHT, GROUP_TIRES });
431         CHANNELS.put(MB_KEY_TIRE_MARKER_FRONT_LEFT, new String[] { OH_CHANNEL_MARKER_FRONT_RIGHT, GROUP_TIRES });
432         CHANNELS.put(MB_KEY_TIRE_MARKER_REAR_RIGHT, new String[] { OH_CHANNEL_MARKER_REAR_LEFT, GROUP_TIRES });
433         CHANNELS.put(MB_KEY_TIRE_MARKER_REAR_LEFT, new String[] { OH_CHANNEL_MARKER_FRONT_LEFT, GROUP_TIRES });
434         CHANNELS.put(MB_KEY_TIRE_SENSOR_AVAILABLE, new String[] { OH_CHANNEL_SENSOR_AVAILABLE, GROUP_TIRES });
435         CHANNELS.put(MB_KEY_TIRE_PRESS_MEAS_TIMESTAMP, new String[] { OH_CHANNEL_LAST_UPDATE, GROUP_TIRES });
436     }
437 }