]> git.basschouten.com Git - openhab-addons.git/commitdiff
[mercedesme] Additional mappings and channels (#17143)
authorBernd Weymann <bernd.weymann@gmail.com>
Thu, 29 Aug 2024 18:58:23 +0000 (20:58 +0200)
committerGitHub <noreply@github.com>
Thu, 29 Aug 2024 18:58:23 +0000 (20:58 +0200)
* starter battery mappings

Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
23 files changed:
bundles/org.openhab.binding.mercedesme/README.md
bundles/org.openhab.binding.mercedesme/src/main/java/org/openhab/binding/mercedesme/internal/Constants.java
bundles/org.openhab.binding.mercedesme/src/main/java/org/openhab/binding/mercedesme/internal/MercedesMeMetadataAdjuster.java
bundles/org.openhab.binding.mercedesme/src/main/java/org/openhab/binding/mercedesme/internal/handler/VehicleHandler.java
bundles/org.openhab.binding.mercedesme/src/main/java/org/openhab/binding/mercedesme/internal/utils/Mapper.java
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/i18n/mercedesme.properties
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/charge-channel-types.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/charge-group.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/eco-channel-types.xml [new file with mode: 0644]
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/eco-group.xml [new file with mode: 0644]
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/hvac-channel-types.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/hvac-group.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/position-channel-group.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/position-channel-types.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/range-channel-types.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/service-channel-types.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/thing-bev.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/thing-combustion.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/thing-hybrid.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/tires-channel-types.xml
bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/update/instructions.xml
bundles/org.openhab.binding.mercedesme/src/test/java/org/openhab/binding/mercedesme/internal/handler/VehicleHandlerTest.java
bundles/org.openhab.binding.mercedesme/src/test/resources/info/AttributeGroupDistribution.json

index 880801824b2f804ab88ee6663f338ceebf960c6f..bc0f395a97fba609a7027b6d5f9a280f8303cd24 100644 (file)
@@ -1,6 +1,6 @@
 # MercedesMe Binding
 
-This binding provides access to your Mercedes Benz vehicle like _Mercedes Me_ Smartphone App .
+This binding provides access to your Mercedes Benz vehicle like _Mercedes Me_ Smartphone App.
 
 ## Installation Instructions
 
@@ -41,8 +41,8 @@ Bridge needs configuration in order to connect properly to your Mercedes Me acco
 | pin             | text    | Mercedes Me Smartphone App PIN          | N/A         | no       | no       |
 | region          | text    | Your region                             | EU          | yes      | no       |
 | refreshInterval | integer | API refresh interval                    | 15          | yes      | no       |
-| callbackIP      | text    | Your region                             | N/A         | yes      | yes      |
-| callbackPort    | integer | API refresh interval                    | N/A         | yes      | yes      |
+| callbackIP      | text    | IP Address of openHAB Device            | N/A         | yes      | yes      |
+| callbackPort    | integer | Port Number of openHAB Device           | N/A         | yes      | yes      |
 
 Set `region` to your location
 
@@ -135,10 +135,6 @@ Channels are separated in groups:
 | [position](#position)            | Positioning Data                                  |
 | [tires](#tires)                  | Tire Information                                  |
 
-## Actions
-
-See [Vehicle Actions](#vehicle-actions) which can be used in rules.
-
 ### Vehicle
 
 Group name: `vehicle`
@@ -327,14 +323,16 @@ States and controls are depending on your vehicle capabilities.
 
 | Channel             | Type                 |  Description                     | Read | Write |
 |---------------------|----------------------|----------------------------------|------|-------|
-| front-left          | Switch               |  Front Left Seat Climatization   | X    |       |
-| front-right         | Switch               |  Front Left Seat Climatization   | X    |       |
-| rear-left           | Switch               |  Front Left Seat Climatization   | X    |       |
-| rear-right          | Switch               |  Front Left Seat Climatization   | X    |       |
-| zone                | Number               |  Selected Climatization Zone     | X    | X     |
-| temperature         | Number:Temperature   |  Desired Temperature for Zone    | X    | X     |
-| activate            | Switch               |  Start/Stop Climatization        | X    | X     |
+| front-left          | Switch               |  AC Seat Front Left              | X    |       |
+| front-right         | Switch               |  AC Seat Front Right             | X    |       |
+| rear-left           | Switch               |  AC Seat Rear Left               | X    |       |
+| rear-right          | Switch               |  AC Seat Rear Right              | X    |       |
+| zone                | Number               |  AC Zone                         | X    | X     |
+| temperature         | Number:Temperature   |  AC Desired Temperature          | X    | X     |
+| activate            | Switch               |  AC Precondition Control         | X    | X     |
+| ac-status           | Number               |  AC Precondition Status          | X    |       |
 | aux-heat            | Switch               |  Auxiliary Heating               | X    | X     |
+| aux-status          | Number               |  Auxiliary Status                | X    |       |
 
 #### Zone Mapping
 
@@ -374,14 +372,35 @@ Fahrenheit
 
 Triggers `TEMPERATURECONFIGURE` from [Command Name Mapping](#command-name-mapping)
 
-#### Activate Switch
+#### AC Precondition Control 
 
 Triggers `PRECONDSTART` and `PRECONDSTOP` from [Command Name Mapping](#command-name-mapping)
  
-#### Auxiliary Heat Switch
+#### AC Precondition Status Mapping
+
+- 0 : No Request
+- 1 : Battery or Fuel Low
+- 2 : Available after Restart Engine
+- 3 : Not Possible, Charging not Finished
+- 4 : General Error</option>
+#### Auxiliary Heating Switch
 
 Triggers `AUXHEATSTART` and `AUXHEATSTOP` from [Command Name Mapping](#command-name-mapping)
 
+#### Auxiliary Status Mapping
+
+- 0 : None
+- 1 : No Budget
+- 2 : Budget Empty
+- 4 : System Error
+- 8 : Running Error
+- 16 : Fuel on Reserve
+- 32 : Reserve Reached
+- 64 : Low Voltage
+- 128 : Low Voltage Operation
+- 256 : Communication Error
+
 ### Service
 
 Group name: `service`
@@ -408,6 +427,16 @@ Traffic light status of the starter battery
 - 0 : Green
 - 1 : Yellow
 - 2 : Red
+- 3 : Service Disabled
+- 4 : Vehicle Not Available
+
+#### Tire Pressure Warnings Mapping
+
+- 0 : No warning
+- 1 : Soft warning
+- 2 : Low warning
+- 3 : Deflation
+- 4 : Unknown warning
 
 ### Range
 
@@ -449,6 +478,8 @@ States and controls are depending on your vehicle capabilities.
 | coupler-dc          | Number               |  Coupler DC Status                     | X    |       |
 | coupler-lock        | Number               |  Coupler Lock Status                   | X    |       |
 | active              | Switch               |  Charging Active                       | X    |       |
+| status              | Number               |  Charge Status                         | X    |       |
+| error               | Number               |  Charge Error                          | X    |       |
 | power               | Number:Power         |  Current Charging Power                | X    |       |
 | end-time            | DateTime             |  Estimated Charging End                | X    |       |
 | program             | Number               |  Selected Charge Program               | X    | X     |
@@ -475,6 +506,25 @@ States and controls are depending on your vehicle capabilities.
 - 0 : Locked
 - 1 : Unlocked
 
+#### Charge Status Mapping
+
+- 0 : Charging
+- 1 : End of Charge
+- 2 : Charge Break
+- 3 : Charge Cable Unplugged
+- 4 : Charging Failure
+- 5 : Slow Charging
+- 6 : Fast Charging
+- 7 : Discharging
+
+#### Charge Error Mapping
+
+- 0 : None
+- 1 : Cable
+- 2 : Charging Disorder
+- 3 : Charging Station
+- 4 : Charging Type
+
 #### Program Mapping
 
 - 0 : DEFAULT_CHARGE_PROGRAM
@@ -540,11 +590,32 @@ In your Mercedes Me App front page
 
 <img src="./doc/ElectricConsumptionUnits.png" width="300" height="300"/>
 
-### Trip Duration
+#### Trip Duration
 
 Shown as String in format `d days, HH:mm`.
 If duration is below 24 hours format is `HH:mm`. 
 
+### ECO Score
+
+Group name: `eco`
+
+All channels `read-only`
+
+| Channel             | Type                   |  Description            |
+|---------------------|------------------------|-------------------------|
+| accel               | Number:Dimensionless   | Acceleration Score      |
+| coasting            | Number:Dimensionless   | Coasting Score          |
+| constant            | Number:Dimensionless   | Constant Score          |
+| bonus               | Number:Length          | Bonus Range             |
+
+The Mercedes ECO Score is aimed to improve your driving behavior.
+
+- Acceleration Score: smooth acceleration e.g. use *eco driving setting*
+- Coasting Score: ideally use only *recuperation* instead of brake
+- Constant Score: drive at constant speed e.g. use *cruise control*
+- Bonus Range: assumed bonus range vs. a *very sportive driver*
+
+
 ### Position
 
 Group name: `position`
@@ -553,8 +624,18 @@ Group name: `position`
 |---------------------|----------------------|-------------------------------------------------|------|-------|
 | heading             | Number:Angle         |  Heading of Vehicle                             | X    |       |
 | gps                 | Point                |  GPS Location Point of Vehicle                  | X    |       |
+| status              | Number               |  Status Positioning                             | X    |       |
 | signal              | Number               |  Request Light or Horn Signal to find Vehicle   |      |  X    |
 
+#### Status Mapping
+
+- 0 : Unknown
+- 1 : Service Inactive
+- 2 : Tracking Inactive
+- 3 : Parked
+- 4 : Ignition On
+- 5 : Ok
+
 #### Signal Settings
 
 Command Options
@@ -585,11 +666,18 @@ All channels `read-only`
 
 #### Sensor Available Mapping
 
-- Not available yet
+- 0 : All Sensors Located
+- 1 : 1-3 Sensors are Missing
+- 2 : All Sensors Missing
+- 3 : System Error
 
 #### Tire Marker Mapping
 
-- Not available yet
+- 0 : No warning
+- 1 : Soft warning
+- 2 : Low warning
+- 3 : Deflation
+- 4 : Unknown warning
 
 ### Commands
 
index 3adf9364de0950f8639d76eae65e99b8407a463e..50d799cb67ebfe90d888bcb0f029c71eab42d260 100644 (file)
@@ -60,6 +60,8 @@ public class Constants {
     public static final String MB_KEY_CHARGE_COUPLER_DC_STATUS = "chargeCouplerDCStatus";
     public static final String MB_KEY_CHARGE_COUPLER_AC_STATUS = "chargeCouplerACStatus";
     public static final String MB_KEY_CHARGE_FLAP_DC_STATUS = "chargeFlapDCStatus";
+    public static final String MB_KEY_CHARGE_STATUS = "chargingstatus";
+    public static final String MB_KEY_CHARGE_ERROR = "chargingErrorDetails";
     public static final String MB_KEY_SERVICEINTERVALDAYS = "serviceintervaldays";
     public static final String MB_KEY_TIREWARNINGSRDK = "tirewarningsrdk";
     public static final String MB_KEY_STARTER_BATTERY_STATE = "starterBatteryState";
@@ -149,6 +151,13 @@ public class Constants {
     public static final String MB_KEY_COMMAND_DOORS_LOCK = "commandDoorsLock";
     public static final String MB_KEY_COMMAND_WINDOWS_OPEN = "commandWindowsOpen";
     public static final String MB_KEY_COMMAND_ENGINE_START = "commandEngineStart";
+    public static final String MB_KEY_POSITION_ERROR = "vehiclePositionErrorCode";
+    public static final String MB_KEY_AUXILIARY_WARNINGS = "auxheatwarnings";
+    public static final String MB_KEY_PRECOND_NOW_ERROR = "precondNowError";
+    public static final String MB_KEY_ECOSCORE_ACCEL = "ecoscoreaccel";
+    public static final String MB_KEY_ECOSCORE_CONSTANT = "ecoscoreconst";
+    public static final String MB_KEY_ECOSCORE_COASTING = "ecoscorefreewhl";
+    public static final String MB_KEY_ECOSCORE_BONUS = "ecoscorebonusrange";
 
     public static final String GROUP_VEHICLE = "vehicle";
     public static final String GROUP_DOORS = "doors";
@@ -159,6 +168,7 @@ public class Constants {
     public static final String GROUP_RANGE = "range";
     public static final String GROUP_CHARGE = "charge";
     public static final String GROUP_TRIP = "trip";
+    public static final String GROUP_ECO = "eco";
     public static final String GROUP_POSITION = "position";
     public static final String GROUP_TIRES = "tires";
     public static final String GROUP_COMMAND = "command";
@@ -247,6 +257,14 @@ public class Constants {
     public static final String OH_CHANNEL_GPS = "gps";
     public static final String OH_CHANNEL_CONS_CONV_UNIT = "cons-conv-unit";
     public static final String OH_CHANNEL_CONS_EV_UNIT = "cons-ev-unit";
+    public static final String OH_CHANNEL_STATUS = "status";
+    public static final String OH_CHANNEL_ERROR = "error";
+    public static final String OH_CHANNEL_AC_STATUS = "ac-status";
+    public static final String OH_CHANNEL_AUX_STATUS = "aux-status";
+    public static final String OH_CHANNEL_ACCEL = "accel";
+    public static final String OH_CHANNEL_COASTING = "coasting";
+    public static final String OH_CHANNEL_CONSTANT = "constant";
+    public static final String OH_CHANNEL_BONUS_RANGE = "bonus";
 
     public static final String CALLBACK_ENDPOINT = "/mb-auth";
     // https://developer.mercedes-benz.com/content-page/api_migration_guide
index 902d605b4a742f5264089f5752592ec38a05f582..c256015918e9706f9648a022bd7ce45695eeba3e 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.mercedesme.internal;
 
+import static org.openhab.binding.mercedesme.internal.Constants.*;
+
 import javax.measure.Unit;
 import javax.measure.quantity.Length;
 
@@ -56,16 +58,17 @@ public class MercedesMeMetadataAdjuster implements RegistryChangeListener<ItemCh
         if (Constants.BINDING_ID.equals(cuid.getBindingId())) {
             MetadataKey key = new MetadataKey("unit", itemName);
             switch (cuid.getId()) {
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "mileage":
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "range-electric":
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "radius-electric":
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "range-fuel":
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "radius-fuel":
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "range-hybrid":
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "radius-hybrid":
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "home-distance":
-                case Constants.GROUP_TRIP + ChannelUID.CHANNEL_GROUP_SEPARATOR + "distance":
-                case Constants.GROUP_TRIP + ChannelUID.CHANNEL_GROUP_SEPARATOR + "distance-reset":
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_MILEAGE:
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_RANGE_ELECTRIC:
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_RADIUS_ELECTRIC:
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_RANGE_FUEL:
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_RADIUS_FUEL:
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_RANGE_HYBRID:
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_RADIUS_HYBRID:
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_HOME_DISTANCE:
+                case GROUP_TRIP + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_DISTANCE:
+                case GROUP_TRIP + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_DISTANCE_RESET:
+                case GROUP_ECO + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_BONUS_RANGE:
                     if (metadataRegistry.get(key) == null) {
                         Unit<Length> lengthUnit = unitProvider.getUnit(Length.class);
                         if (ImperialUnits.FOOT.equals(lengthUnit)) {
@@ -75,17 +78,20 @@ public class MercedesMeMetadataAdjuster implements RegistryChangeListener<ItemCh
                         }
                     }
                     break;
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "soc":
-                case Constants.GROUP_CHARGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "max-soc":
-                case Constants.GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + "fuel-level":
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_SOC:
+                case GROUP_CHARGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_MAX_SOC:
+                case GROUP_RANGE + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_FUEL_LEVEL:
+                case GROUP_ECO + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_ACCEL:
+                case GROUP_ECO + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_COASTING:
+                case GROUP_ECO + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_CONSTANT:
                     if (metadataRegistry.get(key) == null) {
                         metadataRegistry.add(new Metadata(key, Units.PERCENT.getSymbol(), null));
                     }
                     break;
-                case Constants.GROUP_TIRES + ChannelUID.CHANNEL_GROUP_SEPARATOR + "pressure-front-left":
-                case Constants.GROUP_TIRES + ChannelUID.CHANNEL_GROUP_SEPARATOR + "pressure-front-right":
-                case Constants.GROUP_TIRES + ChannelUID.CHANNEL_GROUP_SEPARATOR + "pressure-rear-left":
-                case Constants.GROUP_TIRES + ChannelUID.CHANNEL_GROUP_SEPARATOR + "pressure-rear-right":
+                case GROUP_TIRES + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_PRESSURE_FRONT_LEFT:
+                case GROUP_TIRES + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_PRESSURE_FRONT_RIGHT:
+                case GROUP_TIRES + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_PRESSURE_REAR_LEFT:
+                case GROUP_TIRES + ChannelUID.CHANNEL_GROUP_SEPARATOR + OH_CHANNEL_PRESSURE_REAR_RIGHT:
                     if (metadataRegistry.get(key) == null) {
                         Unit<Length> lengthUnit = unitProvider.getUnit(Length.class);
                         if (ImperialUnits.FOOT.equals(lengthUnit)) {
index be48a9d12d72e2fc2a776a3a20d0f028a0fd5313..4716708ea37bd592fe7a979ffb22a3551a3a0297 100644 (file)
@@ -178,7 +178,9 @@ public class VehicleHandler extends BaseThingHandler {
 
     @Override
     public void dispose() {
-        accountHandler.get().unregisterVin(config.get().vin);
+        accountHandler.ifPresent(ah -> {
+            ah.unregisterVin(config.get().vin);
+        });
         super.dispose();
     }
 
index c12f5b9fa8c86743cd25c821f4c260f59b46c9a9..4a8ff1127431fa0105e4e5cc9e007235a0d7e410 100644 (file)
@@ -93,6 +93,7 @@ public class Mapper {
                 case MB_KEY_RANGELIQUID:
                 case MB_KEY_DISTANCE_START:
                 case MB_KEY_DISTANCE_RESET:
+                case MB_KEY_ECOSCORE_BONUS:
                     Unit<?> lengthUnit = defaultLengthUnit;
                     if (value.hasDistanceUnit()) {
                         observer = new UOMObserver(value.getDistanceUnit().toString());
@@ -196,6 +197,9 @@ public class Mapper {
                 // Percentages
                 case MB_KEY_SOC:
                 case MB_KEY_TANKLEVELPERCENT:
+                case MB_KEY_ECOSCORE_ACCEL:
+                case MB_KEY_ECOSCORE_CONSTANT:
+                case MB_KEY_ECOSCORE_COASTING:
                     double level = Utils.getDouble(value);
                     state = QuantityType.valueOf(level, Units.PERCENT);
                     return new ChannelStateMap(ch[0], ch[1], state);
@@ -239,23 +243,20 @@ public class Mapper {
                 case MB_KEY_CHARGE_COUPLER_DC_STATUS:
                 case MB_KEY_CHARGE_COUPLER_DC_LOCK_STATUS:
                 case MB_KEY_TIRE_SENSOR_AVAILABLE:
-                    int stateNumberInteger = Utils.getInt(value);
-                    if (stateNumberInteger < 0) {
-                        state = UnDefType.UNDEF;
-                    } else {
-                        state = new DecimalType(stateNumberInteger);
-                    }
-                    return new ChannelStateMap(ch[0], ch[1], state);
-
+                case MB_KEY_CHARGE_STATUS:
+                case MB_KEY_CHARGE_ERROR:
                 case MB_KEY_TIRE_MARKER_FRONT_RIGHT:
                 case MB_KEY_TIRE_MARKER_FRONT_LEFT:
                 case MB_KEY_TIRE_MARKER_REAR_RIGHT:
                 case MB_KEY_TIRE_MARKER_REAR_LEFT:
-                    double stateNumberDouble = Utils.getDouble(value);
-                    if (stateNumberDouble < 0) {
+                case MB_KEY_POSITION_ERROR:
+                case MB_KEY_AUXILIARY_WARNINGS:
+                case MB_KEY_PRECOND_NOW_ERROR:
+                    int stateNumberInteger = Utils.getInt(value);
+                    if (stateNumberInteger < 0) {
                         state = UnDefType.UNDEF;
                     } else {
-                        state = new DecimalType(stateNumberDouble);
+                        state = new DecimalType(stateNumberInteger);
                     }
                     return new ChannelStateMap(ch[0], ch[1], state);
 
@@ -384,6 +385,8 @@ public class Mapper {
         CHANNELS.put(MB_KEY_PRECOND_SEAT_FRONT_LEFT, new String[] { OH_CHANNEL_FRONT_LEFT, GROUP_HVAC });
         CHANNELS.put(MB_KEY_PRECOND_SEAT_REAR_RIGHT, new String[] { OH_CHANNEL_REAR_RIGHT, GROUP_HVAC });
         CHANNELS.put(MB_KEY_PRECOND_SEAT_REAR_LEFT, new String[] { OH_CHANNEL_REAR_LEFT, GROUP_HVAC });
+        CHANNELS.put(MB_KEY_AUXILIARY_WARNINGS, new String[] { OH_CHANNEL_AUX_STATUS, GROUP_HVAC });
+        CHANNELS.put(MB_KEY_PRECOND_NOW_ERROR, new String[] { OH_CHANNEL_AC_STATUS, GROUP_HVAC });
         // temperaturePoints - special handling: sets zone & temperature
 
         CHANNELS.put(MB_KEY_STARTER_BATTERY_STATE, new String[] { OH_CHANNEL_STARTER_BATTERY, GROUP_SERVICE });
@@ -407,10 +410,13 @@ public class Mapper {
         CHANNELS.put(MB_KEY_CHARGE_COUPLER_DC_STATUS, new String[] { OH_CHANNEL_COUPLER_DC, GROUP_CHARGE });
         CHANNELS.put(MB_KEY_CHARGE_COUPLER_DC_LOCK_STATUS, new String[] { OH_CHANNEL_COUPLER_LOCK, GROUP_CHARGE });
         CHANNELS.put(MB_KEY_CHARGINGACTIVE, new String[] { OH_CHANNEL_ACTIVE, GROUP_CHARGE });
+        CHANNELS.put(MB_KEY_CHARGE_STATUS, new String[] { OH_CHANNEL_STATUS, GROUP_CHARGE });
+        CHANNELS.put(MB_KEY_CHARGE_ERROR, new String[] { OH_CHANNEL_ERROR, GROUP_CHARGE });
         CHANNELS.put(MB_KEY_CHARGING_POWER, new String[] { OH_CHANNEL_POWER, GROUP_CHARGE });
         CHANNELS.put(MB_KEY_ENDOFCHARGETIME, new String[] { OH_CHANNEL_END_TIME, GROUP_CHARGE });
 
         CHANNELS.put(MB_KEY_POSITION_HEADING, new String[] { OH_CHANNEL_HEADING, GROUP_POSITION });
+        CHANNELS.put(MB_KEY_POSITION_ERROR, new String[] { OH_CHANNEL_STATUS, GROUP_POSITION });
 
         CHANNELS.put(MB_KEY_DISTANCE_START, new String[] { OH_CHANNEL_DISTANCE, GROUP_TRIP });
         CHANNELS.put(MB_KEY_DRIVEN_TIME_START, new String[] { OH_CHANNEL_TIME, GROUP_TRIP });
@@ -423,6 +429,11 @@ public class Mapper {
         CHANNELS.put(MB_KEY_ELECTRICCONSUMPTIONRESET, new String[] { OH_CHANNEL_CONS_EV_RESET, GROUP_TRIP });
         CHANNELS.put(MB_KEY_LIQUIDCONSUMPTIONRESET, new String[] { OH_CHANNEL_CONS_CONV_RESET, GROUP_TRIP });
 
+        CHANNELS.put(MB_KEY_ECOSCORE_ACCEL, new String[] { OH_CHANNEL_ACCEL, GROUP_ECO });
+        CHANNELS.put(MB_KEY_ECOSCORE_CONSTANT, new String[] { OH_CHANNEL_CONSTANT, GROUP_ECO });
+        CHANNELS.put(MB_KEY_ECOSCORE_COASTING, new String[] { OH_CHANNEL_COASTING, GROUP_ECO });
+        CHANNELS.put(MB_KEY_ECOSCORE_BONUS, new String[] { OH_CHANNEL_BONUS_RANGE, GROUP_ECO });
+
         CHANNELS.put(MB_KEY_TIREPRESSURE_REAR_RIGHT, new String[] { OH_CHANNEL_PRESSURE_REAR_RIGHT, GROUP_TIRES });
         CHANNELS.put(MB_KEY_TIREPRESSURE_FRONT_RIGHT, new String[] { OH_CHANNEL_PRESSURE_FRONT_RIGHT, GROUP_TIRES });
         CHANNELS.put(MB_KEY_TIREPRESSURE_REAR_LEFT, new String[] { OH_CHANNEL_PRESSURE_REAR_LEFT, GROUP_TIRES });
index 1260417c915a3416351324cb2c6c2af9e332f37b..e3638f30acfd89f3b8a39abd1a549749e2f7bb2e 100644 (file)
@@ -49,6 +49,8 @@ channel-group-type.mercedesme.charge-values.label = Charging Data
 channel-group-type.mercedesme.command-values.label = Status of Last Command
 channel-group-type.mercedesme.door-values.label = Detailed Door Status
 channel-group-type.mercedesme.door-values.description = Detailed Status of all Doors and Windows
+channel-group-type.mercedesme.eco-values.label = ECO Score
+channel-group-type.mercedesme.eco-values.description = Economic score for acceleration, coasting and constant driving plus bonus range
 channel-group-type.mercedesme.hvac-values.label = Vehicle Climate Control
 channel-group-type.mercedesme.lock-ev-values.label = Lock Status
 channel-group-type.mercedesme.lock-ev-values.description = Door Lock Status
@@ -77,14 +79,39 @@ channel-group-type.mercedesme.window-values.description = Detailed Status Window
 
 # channel types
 
-channel-type.mercedesme.active-hvac.label = AC Control
+channel-type.mercedesme.ac-status.label = AC Precondition Status
+channel-type.mercedesme.ac-status.description = Status of precondition air conditioning
+channel-type.mercedesme.ac-status.state.option.0 = No Request
+channel-type.mercedesme.ac-status.state.option.1 = Battery or Fuel Low
+channel-type.mercedesme.ac-status.state.option.2 = Available after Restart Engine
+channel-type.mercedesme.ac-status.state.option.3 = Not Possible, Charging not Finished
+channel-type.mercedesme.ac-status.state.option.4 = General Error
+channel-type.mercedesme.accel.label = Acceleration Score
+channel-type.mercedesme.accel.description = Score for smooth acceleration
+channel-type.mercedesme.active-hvac.label = AC Precondition Control
+channel-type.mercedesme.active-hvac.description = Switch on/off precondition air conditioning
 channel-type.mercedesme.active.label = Charge Active
 channel-type.mercedesme.auto-unlock.label = Coupler Auto Unlock
 channel-type.mercedesme.auto-unlock.description = Auto unlock coupler after charging
 channel-type.mercedesme.aux-heat.label = Auxiliary Heating Control
+channel-type.mercedesme.aux-heat.description = Switch on/off auxiliary heating
+channel-type.mercedesme.aux-status.label = Auxiliary Heating Status
+channel-type.mercedesme.aux-status.description = Auxiliary heating status
+channel-type.mercedesme.aux-status.state.option.0 = None
+channel-type.mercedesme.aux-status.state.option.1 = No Budget
+channel-type.mercedesme.aux-status.state.option.2 = Budget Empty
+channel-type.mercedesme.aux-status.state.option.4 = System Error
+channel-type.mercedesme.aux-status.state.option.8 = Running Error
+channel-type.mercedesme.aux-status.state.option.16 = Fuel on Reserve
+channel-type.mercedesme.aux-status.state.option.32 = Reserve Reached
+channel-type.mercedesme.aux-status.state.option.64 = Low Voltage
+channel-type.mercedesme.aux-status.state.option.128 = Low Voltage Operation
+channel-type.mercedesme.aux-status.state.option.256 = Communication Error
 channel-type.mercedesme.avg-speed-reset.label = Rst Average Speed
 channel-type.mercedesme.avg-speed-reset.description = Average speed since last Reset
 channel-type.mercedesme.avg-speed.label = Trip Average Speed
+channel-type.mercedesme.bonus.label = Bonus Range
+channel-type.mercedesme.bonus.description = Additional range vs. very sportive driver
 channel-type.mercedesme.brake-fluid.label = Brake Fluid
 channel-type.mercedesme.brake-lining-wear.label = Brake Lining Wear
 channel-type.mercedesme.charge-flap.label = Charge Flap
@@ -96,7 +123,11 @@ channel-type.mercedesme.cmd-last-update.label = Command Updated
 channel-type.mercedesme.cmd-last-update.state.pattern = %1$tA, %1$td.%1$tm. %1$tH:%1$tM
 channel-type.mercedesme.cmd-name.label = Command Name
 channel-type.mercedesme.cmd-state.label = Command State
+channel-type.mercedesme.coasting.label = Coasting Score
+channel-type.mercedesme.coasting.description = Score for driving without braking
 channel-type.mercedesme.command-capabilities.label = Command Capabilities
+channel-type.mercedesme.constant.label = Constant Score
+channel-type.mercedesme.constant.description = Score for driving with constant speed
 channel-type.mercedesme.consumption-conv-reset.label = Avg Cons Rst Fuel
 channel-type.mercedesme.consumption-conv-reset.description = Average consumption since last reset fuel
 channel-type.mercedesme.consumption-conv-unit.label = Avg Cons Unit Fuel
@@ -134,9 +165,16 @@ channel-type.mercedesme.driven-time-reset.label = Rst Driving Time
 channel-type.mercedesme.driven-time-reset.description = Driving time since last Reset
 channel-type.mercedesme.driven-time.label = Trip String Time
 channel-type.mercedesme.end-time.label = Charge End Estimation
-channel-type.mercedesme.end-time.state.pattern = %1$tH:%1$tM
+channel-type.mercedesme.end-time.state.pattern = %1$td.%1$tm. %1$tH:%1$tM
 channel-type.mercedesme.engine-hood.label = Engine Hood
 channel-type.mercedesme.engine.label = Engine Warning
+channel-type.mercedesme.error-charge.label = Charge Error
+channel-type.mercedesme.error-charge.description = Actual charging error if available
+channel-type.mercedesme.error-charge.state.option.0 = None
+channel-type.mercedesme.error-charge.state.option.1 = Cable
+channel-type.mercedesme.error-charge.state.option.2 = Charging Disorder
+channel-type.mercedesme.error-charge.state.option.3 = Charging Station
+channel-type.mercedesme.error-charge.state.option.4 = Charging Type
 channel-type.mercedesme.feature-capabilities.label = Feature Capabilities
 channel-type.mercedesme.flip-window.label = Flip Window
 channel-type.mercedesme.front-left-hvac.label = AC Seat Front Left
@@ -256,6 +294,10 @@ channel-type.mercedesme.rooftop.state.option.0 = Unlocked
 channel-type.mercedesme.rooftop.state.option.1 = Open and locked
 channel-type.mercedesme.rooftop.state.option.2 = Closed and locked
 channel-type.mercedesme.sensor-available.label = Tire Sensor Available
+channel-type.mercedesme.sensor-available.state.option.0 = All Sensors Located
+channel-type.mercedesme.sensor-available.state.option.1 = 1-3 Sensors are Missing
+channel-type.mercedesme.sensor-available.state.option.2 = All Sensors Missing
+channel-type.mercedesme.sensor-available.state.option.3 = System Error
 channel-type.mercedesme.service-days.label = Service in Days
 channel-type.mercedesme.signal.label = Position Signal
 channel-type.mercedesme.signal.state.option.0 = Position Lights
@@ -267,6 +309,25 @@ channel-type.mercedesme.starter-battery.label = Starter Battery Status
 channel-type.mercedesme.starter-battery.state.option.0 = Green
 channel-type.mercedesme.starter-battery.state.option.1 = Yellow
 channel-type.mercedesme.starter-battery.state.option.2 = Red
+channel-type.mercedesme.starter-battery.state.option.3 = Service Disabled
+channel-type.mercedesme.starter-battery.state.option.4 = Vehicle Not Available
+channel-type.mercedesme.status-charge.label = Charge Status
+channel-type.mercedesme.status-charge.description = Actual charging status
+channel-type.mercedesme.status-charge.state.option.0 = Charging
+channel-type.mercedesme.status-charge.state.option.1 = End of Charge
+channel-type.mercedesme.status-charge.state.option.2 = Charge Break
+channel-type.mercedesme.status-charge.state.option.3 = Charge Cable Unplugged
+channel-type.mercedesme.status-charge.state.option.4 = Charging Failure
+channel-type.mercedesme.status-charge.state.option.5 = Slow Charging
+channel-type.mercedesme.status-charge.state.option.6 = Fast Charging
+channel-type.mercedesme.status-charge.state.option.7 = Discharging
+channel-type.mercedesme.status-pos.label = Status Positioning
+channel-type.mercedesme.status-pos.state.option.0 = Unknown
+channel-type.mercedesme.status-pos.state.option.1 = Service Inactive
+channel-type.mercedesme.status-pos.state.option.2 = Tracking Inactive
+channel-type.mercedesme.status-pos.state.option.3 = Parked
+channel-type.mercedesme.status-pos.state.option.4 = Ignition On
+channel-type.mercedesme.status-pos.state.option.5 = Ok
 channel-type.mercedesme.sunroof-front-blind.label = Sun Roof Front Blind
 channel-type.mercedesme.sunroof-rear-blind.label = Sun Roof Rear Blind
 channel-type.mercedesme.sunroof.label = Sun Roof
@@ -280,8 +341,13 @@ channel-type.mercedesme.sunroof.state.option.6 = Closing
 channel-type.mercedesme.sunroof.command.option.0 = Close
 channel-type.mercedesme.sunroof.command.option.1 = Open
 channel-type.mercedesme.sunroof.command.option.2 = Lift
-channel-type.mercedesme.temperature-hvac.label = AC Temperature
+channel-type.mercedesme.temperature-hvac.label = AC Setpoint Temperature
 channel-type.mercedesme.tires-rdk.label = Tire Pressure Warnings
+channel-type.mercedesme.tires-rdk.state.option.0 = No warning
+channel-type.mercedesme.tires-rdk.state.option.1 = Soft warning
+channel-type.mercedesme.tires-rdk.state.option.2 = Low warning
+channel-type.mercedesme.tires-rdk.state.option.3 = Deflation
+channel-type.mercedesme.tires-rdk.state.option.4 = Unknown warning
 channel-type.mercedesme.uncharged.label = Uncharged Battery Energy
 channel-type.mercedesme.wash-water.label = Wash Water Low
 channel-type.mercedesme.windows.label = Windows Status/Control
@@ -293,7 +359,7 @@ channel-type.mercedesme.windows.command.option.1 = Close
 channel-type.mercedesme.windows.command.option.2 = Open
 channel-type.mercedesme.zone-hvac.label = AC Zone
 
-# channel types
+# action types
 
 actionPoiLabel = Send POI to Vehicle
 actionPoiDescription = Send POI with name, latitude and longitude
@@ -303,6 +369,9 @@ latitudeLabel = Latitude
 latitudeDescription = Latitude of the location
 longitudeLabel = Longitude
 longitudeDescription = Longitude of the location
+
+# thing status types
+
 mercedesme.account.status.authorization-needed = Manual Authorization needed at {0}
 mercedesme.account.status.email-missing = EMail missing
 mercedesme.account.status.region-missing = Region missing
index adbcce18cd6feb7c82f3fd171885c8f9380c1941..b7d329715bc3bd694ad8889ec7d7d93bbd26c6d3 100644 (file)
                <label>Charge Active</label>
                <state readOnly="true"/>
        </channel-type>
+       <channel-type id="status-charge">
+               <item-type>Number</item-type>
+               <label>Charge Status</label>
+               <description>Actual charging status</description>
+               <state readOnly="true">
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/master/MBCarKit/MBCarKit/Common/Enums/Status/ZEVTypes.swift#L92 -->
+                       <options>
+                               <option value="0">Charging</option>
+                               <option value="1">End of Charge</option>
+                               <option value="2">Charge Break</option>
+                               <option value="3">Charge Cable Unplugged</option>
+                               <option value="4">Charging Failure</option>
+                               <option value="5">Slow Charging</option>
+                               <option value="6">Fast Charging</option>
+                               <option value="7">Discharging</option>
+                       </options>
+               </state>
+       </channel-type>
+       <channel-type id="error-charge">
+               <item-type>Number</item-type>
+               <label>Charge Error</label>
+               <description>Actual charging error if available</description>
+               <state readOnly="true">
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/master/MBCarKit/MBCarKit/Common/Enums/Status/ZEVTypes.swift#L19 -->
+                       <options>
+                               <option value="0">None</option>
+                               <option value="1">Cable</option>
+                               <option value="2">Charging Disorder</option>
+                               <option value="3">Charging Station</option>
+                               <option value="4">Charging Type</option>
+                       </options>
+               </state>
+       </channel-type>
        <channel-type id="power">
                <item-type>Number:Power</item-type>
                <label>Charge Power</label>
index 54711f1b99b8b09ab563f9c4eaed6a7c4b99ba3e..5817e9e8875baa8f33422a5bec9572e2d2d5d859 100644 (file)
@@ -11,6 +11,8 @@
                        <channel id="coupler-dc" typeId="coupler-dc"/>
                        <channel id="coupler-lock" typeId="coupler-lock"/>
                        <channel id="active" typeId="active"/>
+                       <channel id="status" typeId="status-charge"/>
+                       <channel id="error" typeId="error-charge"/>
                        <channel id="power" typeId="power"/>
                        <channel id="end-time" typeId="end-time"/>
                        <channel id="program" typeId="program"/>
diff --git a/bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/eco-channel-types.xml b/bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/eco-channel-types.xml
new file mode 100644 (file)
index 0000000..11217da
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="mercedesme"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+       <channel-type id="accel">
+               <item-type>Number:Dimensionless</item-type>
+               <label>Acceleration Score</label>
+               <description>Score for smooth acceleration</description>
+               <state readOnly="true"/>
+       </channel-type>
+       <channel-type id="coasting">
+               <item-type>Number:Dimensionless</item-type>
+               <label>Coasting Score</label>
+               <description>Score for driving without braking</description>
+               <state readOnly="true"/>
+       </channel-type>
+       <channel-type id="constant">
+               <item-type>Number:Dimensionless</item-type>
+               <label>Constant Score</label>
+               <description>Score for driving with constant speed</description>
+               <state readOnly="true"/>
+       </channel-type>
+       <channel-type id="bonus">
+               <item-type>Number:Length</item-type>
+               <label>Bonus Range</label>
+               <description>Additional range vs. very sportive driver</description>
+               <state pattern="%d %unit%" readOnly="true"/>
+       </channel-type>
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/eco-group.xml b/bundles/org.openhab.binding.mercedesme/src/main/resources/OH-INF/thing/eco-group.xml
new file mode 100644 (file)
index 0000000..47b9489
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="mercedesme"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+       <channel-group-type id="eco-values">
+               <label>ECO Score</label>
+               <description>Economic score for acceleration, coasting and constant driving plus bonus range</description>
+               <channels>
+                       <channel id="accel" typeId="accel"/>
+                       <channel id="coasting" typeId="coasting"/>
+                       <channel id="constant" typeId="constant"/>
+                       <channel id="bonus" typeId="bonus"/>
+               </channels>
+       </channel-group-type>
+</thing:thing-descriptions>
index adbb8795916d0fb429e5dbbfbc40723f545f968e..eb1090ff3025064d6ebe329b6e5e99e675a58384 100644 (file)
        </channel-type>
        <channel-type id="temperature-hvac">
                <item-type>Number:Temperature</item-type>
-               <label>AC Temperature</label>
+               <label>AC Setpoint Temperature</label>
                <autoUpdatePolicy>veto</autoUpdatePolicy>
        </channel-type>
        <channel-type id="active-hvac">
                <item-type>Switch</item-type>
-               <label>AC Control</label>
+               <label>AC Precondition Control</label>
+               <description>Switch on/off precondition air conditioning</description>
                <autoUpdatePolicy>veto</autoUpdatePolicy>
        </channel-type>
+       <channel-type id="ac-status">
+               <item-type>Number</item-type>
+               <label>AC Precondition Status</label>
+               <description>Status of precondition air conditioning</description>
+               <state>
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/8592099d9b0d94161517ce2bc7469562f86c9886/MBCarKit/MBCarKit/Common/Enums/Status/ZEVTypes.swift#L235 -->
+                       <options>
+                               <option value="0">No Request</option>
+                               <option value="1">Battery or Fuel Low</option>
+                               <option value="2">Available after Restart Engine</option>
+                               <option value="3">Not Possible, Charging not Finished</option>
+                               <option value="4">General Error</option>
+                       </options>
+               </state>
+       </channel-type>
        <channel-type id="front-left-hvac">
                <item-type>Switch</item-type>
                <label>AC Seat Front Left</label>
        <channel-type id="aux-heat">
                <item-type>Switch</item-type>
                <label>Auxiliary Heating Control</label>
+               <description>Switch on/off auxiliary heating</description>
                <autoUpdatePolicy>veto</autoUpdatePolicy>
        </channel-type>
+       <channel-type id="aux-status">
+               <item-type>Number</item-type>
+               <label>Auxiliary Heating Status</label>
+               <description>Auxiliary heating status</description>
+               <state>
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/8592099d9b0d94161517ce2bc7469562f86c9886/MBCarKit/MBCarKit/Common/Enums/Status/AuxheatTypes.swift#L66 -->
+                       <options>
+                               <option value="0">None</option>
+                               <option value="1">No Budget</option>
+                               <option value="2">Budget Empty</option>
+                               <option value="4">System Error</option>
+                               <option value="8">Running Error</option>
+                               <option value="16">Fuel on Reserve</option>
+                               <option value="32">Reserve Reached</option>
+                               <option value="64">Low Voltage</option>
+                               <option value="128">Low Voltage Operation</option>
+                               <option value="256">Communication Error</option>
+                       </options>
+               </state>
+       </channel-type>
 </thing:thing-descriptions>
index 20a5d26ebbe8a7613e2a3bf85e2f3d8bed41bb64..27713059ded586458a27e85e497777770e19c50c 100644 (file)
@@ -13,7 +13,9 @@
                        <channel id="zone" typeId="zone-hvac"/>
                        <channel id="temperature" typeId="temperature-hvac"/>
                        <channel id="active" typeId="active-hvac"/>
+                       <channel id="ac-status" typeId="ac-status"/>
                        <channel id="aux-heat" typeId="aux-heat"/>
+                       <channel id="aux-status" typeId="aux-status"/>
                </channels>
        </channel-group-type>
 </thing:thing-descriptions>
index 5541d1200c45589ddaebec7fd3b2ecb71427387b..eaa39538bd909ca27c3876631900ff6644706cda 100644 (file)
@@ -9,6 +9,7 @@
                <channels>
                        <channel id="heading" typeId="heading"/>
                        <channel id="gps" typeId="gps"/>
+                       <channel id="status" typeId="status-pos"/>
                        <channel id="signal" typeId="signal"/>
                </channels>
        </channel-group-type>
index e33569638f5fbb77af01cdb4b981485bb72ce093..0f7ae617bb2805ab557cb532f65f54674c1ac480 100644 (file)
                <item-type>Location</item-type>
                <label>Position GPS</label>
        </channel-type>
+       <channel-type id="status-pos">
+               <item-type>Number</item-type>
+               <label>Status Positioning</label>
+               <state>
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/8592099d9b0d94161517ce2bc7469562f86c9886/MBCarKit/MBCarKit/Common/Enums/Status/PositionErrorState.swift#L8 -->
+                       <options>
+                               <option value="0">Unknown</option>
+                               <option value="1">Service Inactive</option>
+                               <option value="2">Tracking Inactive</option>
+                               <option value="3">Parked</option>
+                               <option value="4">Ignition On</option>
+                               <option value="5">Ok</option>
+                       </options>
+               </state>
+       </channel-type>
        <channel-type id="signal">
                <item-type>Number</item-type>
                <label>Position Signal</label>
index a523f926bf2ff34a571da8558cb48685b30e4ea2..8861216318cd3783eed6157af9be7842dc39e620 100644 (file)
@@ -26,7 +26,7 @@
        <channel-type id="soc">
                <item-type>Number:Dimensionless</item-type>
                <label>Battery Charge Level</label>
-               <state pattern="%d %" readOnly="true"/>
+               <state pattern="%d %%" readOnly="true"/>
        </channel-type>
        <channel-type id="charged">
                <item-type>Number:Energy</item-type>
index cc0e54ce10edd8d246334a5e77ab5de62075fbee..2229bea2e3aadd961adab6802b9b77b095472697 100644 (file)
@@ -7,10 +7,13 @@
                <item-type>Number</item-type>
                <label>Starter Battery Status</label>
                <state readOnly="true">
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/master/MBCarKit/MBCarKit/Common/Enums/Status/StarterBatteryState.swift -->
                        <options>
                                <option value="0">Green</option>
                                <option value="1">Yellow</option>
                                <option value="2">Red</option>
+                               <option value="3">Service Disabled</option>
+                               <option value="4">Vehicle Not Available </option>
                        </options>
                </state>
        </channel-type>
                <item-type>Number</item-type>
                <label>Tire Pressure Warnings</label>
                <state readOnly="true">
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/master/MBCarKit/MBCarKit/Common/Enums/Status/TireTypes.swift#L51 -->
+                       <options>
+                               <option value="0">No warning</option>
+                               <option value="1">Soft warning</option>
+                               <option value="2">Low warning</option>
+                               <option value="3">Deflation</option>
+                               <option value="4">Unknown warning</option>
+                       </options>
                </state>
        </channel-type>
        <channel-type id="service-days">
index 357d492e68d5b42c9ada2b1d9b0b19995fe4aa02..92f087b12abe0a5edeb9a13a2f4689678c7129ef 100644 (file)
                        <channel-group id="range" typeId="range-ev-values"/>
                        <channel-group id="charge" typeId="charge-values"/>
                        <channel-group id="trip" typeId="trip-ev-values"/>
+                       <channel-group id="eco" typeId="eco-values"/>
                        <channel-group id="position" typeId="position-values"/>
                        <channel-group id="tires" typeId="tires-values"/>
                        <channel-group id="command" typeId="command-values"/>
                </channel-groups>
 
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
+
                <config-description-ref uri="thing-type:mercedesme:bev"/>
        </thing-type>
 </thing:thing-descriptions>
index 977dd7af64264a000cead352d29904f33dbe1b16..dbfe23533d5ef223526784e358d7f93e9842110b 100644 (file)
                        <channel-group id="service" typeId="service-values"/>
                        <channel-group id="range" typeId="range-conv-values"/>
                        <channel-group id="trip" typeId="trip-conv-values"/>
+                       <channel-group id="eco" typeId="eco-values"/>
                        <channel-group id="position" typeId="position-values"/>
                        <channel-group id="tires" typeId="tires-values"/>
                        <channel-group id="command" typeId="command-values"/>
                </channel-groups>
 
                <properties>
-                       <property name="thingTypeVersion">1</property>
+                       <property name="thingTypeVersion">2</property>
                </properties>
 
                <config-description-ref uri="thing-type:mercedesme:conv"/>
index e55fa8d1c07de08e028f8a2d868a9fa49436369f..907f8009f4712f265b6f4a56c07270418a5eed33 100644 (file)
                        <channel-group id="range" typeId="range-hybrid-values"/>
                        <channel-group id="charge" typeId="charge-values"/>
                        <channel-group id="trip" typeId="trip-hybrid-values"/>
+                       <channel-group id="eco" typeId="eco-values"/>
                        <channel-group id="position" typeId="position-values"/>
                        <channel-group id="tires" typeId="tires-values"/>
                        <channel-group id="command" typeId="command-values"/>
                </channel-groups>
 
                <properties>
-                       <property name="thingTypeVersion">1</property>
+                       <property name="thingTypeVersion">2</property>
                </properties>
 
                <config-description-ref uri="thing-type:mercedesme:hybrid"/>
index ace31ffb7860ad0e66864445ffe04e60b28a1099..a5da9c209bf83c09f22288057ae22748f9c17a73 100644 (file)
        <channel-type id="sensor-available">
                <item-type>Number</item-type>
                <label>Tire Sensor Available</label>
-               <state readOnly="true"/>
+               <state readOnly="true">
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/master/MBCarKit/MBCarKit/Common/Enums/Status/TireTypes.swift#L77 -->
+                       <options>
+                               <option value="0">All Sensors Located</option>
+                               <option value="1">1-3 Sensors are Missing</option>
+                               <option value="2">All Sensors Missing</option>
+                               <option value="3">System Error</option>
+                       </options>
+               </state>
        </channel-type>
        <channel-type id="marker-front-right">
                <item-type>Number</item-type>
                <label>Tire Warning Front Right</label>
                <state readOnly="true">
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/master/MBCarKit/MBCarKit/Common/Enums/Status/TireTypes.swift#L51 -->
                        <options>
                                <option value="0">No warning</option>
                                <option value="1">Soft warning</option>
@@ -45,6 +54,7 @@
                <item-type>Number</item-type>
                <label>Tire Warning Rear Right</label>
                <state readOnly="true">
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/master/MBCarKit/MBCarKit/Common/Enums/Status/TireTypes.swift#L51 -->
                        <options>
                                <option value="0">No warning</option>
                                <option value="1">Soft warning</option>
@@ -58,6 +68,7 @@
                <item-type>Number</item-type>
                <label>Tire Warning Front Left</label>
                <state readOnly="true">
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/master/MBCarKit/MBCarKit/Common/Enums/Status/TireTypes.swift#L51 -->
                        <options>
                                <option value="0">No warning</option>
                                <option value="1">Soft warning</option>
@@ -71,6 +82,7 @@
                <item-type>Number</item-type>
                <label>Tire Warning Rear Left</label>
                <state readOnly="true">
+                       <!-- see https://github.com/mercedes-benz/MBSDK-CarKit-iOS/blob/master/MBCarKit/MBCarKit/Common/Enums/Status/TireTypes.swift#L51 -->
                        <options>
                                <option value="0">No warning</option>
                                <option value="1">Soft warning</option>
index 744a25359b9131a80c9c709ab600e53b79946fc9..f95be9a969dd6b19224574daa1bdd8d7642864a4 100644 (file)
        xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
        xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
 
+       <thing-type uid="mercedesme:bev">
+               <instruction-set targetVersion="1">
+                       <update-channel id="aux-heat" groupIds="hvac">
+                               <type>mercedesme:aux-heat</type>
+                               <label>Auxiliary Heating Control</label>
+                               <description>Switch on/off auxiliary heating</description>
+                       </update-channel>
+                       <add-channel id="aux-status" groupIds="hvac">
+                               <type>mercedesme:aux-status</type>
+                               <label>Auxiliary Heating Status</label>
+                               <description>Auxiliary heating status</description>
+                       </add-channel>
+                       <update-channel id="active-hvac" groupIds="hvac">
+                               <type>mercedesme:ac-status</type>
+                               <label>AC Precondition Control</label>
+                               <description>Switch on/off precondition air conditioning</description>
+                       </update-channel>
+                       <update-channel id="temperature-hvac" groupIds="hvac">
+                               <type>mercedesme:temperature-hvac</type>
+                               <label> AC Setpoint Temperature</label>
+                       </update-channel>
+                       <add-channel id="ac-status" groupIds="hvac">
+                               <type>mercedesme:ac-status</type>
+                               <label>AC Precondition Status</label>
+                               <description>Status of precondition air conditioning</description>
+                       </add-channel>
+                       <add-channel id="status-charge" groupIds="charge">
+                               <type>mercedesme:status-charge</type>
+                               <label>Charge Status</label>
+                               <description>Actual charging status</description>
+                       </add-channel>
+                       <add-channel id="error-charge" groupIds="charge">
+                               <type>mercedesme:error-charge</type>
+                               <label>Charge Error</label>
+                               <description>Actual charging error if available</description>
+                       </add-channel>
+                       <add-channel id="accel" groupIds="eco">
+                               <type>mercedesme:accel</type>
+                               <label>Acceleration Score</label>
+                               <description>Score for smooth acceleration</description>
+                       </add-channel>
+                       <add-channel id="coasting" groupIds="eco">
+                               <type>mercedesme:coasting</type>
+                               <label>Coasting Score</label>
+                               <description>Score for driving without braking</description>
+                       </add-channel>
+                       <add-channel id="constant" groupIds="eco">
+                               <type>mercedesme:constant</type>
+                               <label>Constant Score</label>
+                               <description>Score for driving with constant speed</description>
+                       </add-channel>
+                       <add-channel id="bonus" groupIds="eco">
+                               <type>mercedesme:bonus</type>
+                               <label>Bonus Range</label>
+                               <description>Additional range vs. very sportive driver</description>
+                       </add-channel>
+                       <add-channel id="status-pos" groupIds="position">
+                               <type>mercedesme:status-pos</type>
+                               <label>Status Positioning</label>
+                       </add-channel>
+               </instruction-set>
+       </thing-type>
+
        <thing-type uid="mercedesme:hybrid">
                <instruction-set targetVersion="1">
                        <update-channel id="cons-conv-reset" groupIds="trip">
                                <type>mercedesme:consumption-conv-reset</type>
                        </update-channel>
                </instruction-set>
+               <instruction-set targetVersion="2">
+                       <update-channel id="aux-heat" groupIds="hvac">
+                               <type>mercedesme:aux-heat</type>
+                               <label>Auxiliary Heating Control</label>
+                               <description>Switch on/off auxiliary heating</description>
+                       </update-channel>
+                       <add-channel id="aux-status" groupIds="hvac">
+                               <type>mercedesme:aux-status</type>
+                               <label>Auxiliary Heating Status</label>
+                               <description>Auxiliary heating status</description>
+                       </add-channel>
+                       <update-channel id="active-hvac" groupIds="hvac">
+                               <type>mercedesme:ac-status</type>
+                               <label>AC Precondition Control</label>
+                               <description>Switch on/off precondition air conditioning</description>
+                       </update-channel>
+                       <update-channel id="temperature-hvac" groupIds="hvac">
+                               <type>mercedesme:temperature-hvac</type>
+                               <label> AC Setpoint Temperature</label>
+                       </update-channel>
+                       <add-channel id="ac-status" groupIds="hvac">
+                               <type>mercedesme:ac-status</type>
+                               <label>AC Precondition Status</label>
+                               <description>Status of precondition air conditioning</description>
+                       </add-channel>
+                       <add-channel id="status-charge" groupIds="charge">
+                               <type>mercedesme:status-charge</type>
+                               <label>Charge Status</label>
+                               <description>Actual charging status</description>
+                       </add-channel>
+                       <add-channel id="error-charge" groupIds="charge">
+                               <type>mercedesme:error-charge</type>
+                               <label>Charge Error</label>
+                               <description>Actual charging error if available</description>
+                       </add-channel>
+                       <add-channel id="accel" groupIds="eco">
+                               <type>mercedesme:accel</type>
+                               <label>Acceleration Score</label>
+                               <description>Score for smooth acceleration</description>
+                       </add-channel>
+                       <add-channel id="coasting" groupIds="eco">
+                               <type>mercedesme:coasting</type>
+                               <label>Coasting Score</label>
+                               <description>Score for driving without braking</description>
+                       </add-channel>
+                       <add-channel id="constant" groupIds="eco">
+                               <type>mercedesme:constant</type>
+                               <label>Constant Score</label>
+                               <description>Score for driving with constant speed</description>
+                       </add-channel>
+                       <add-channel id="bonus" groupIds="eco">
+                               <type>mercedesme:bonus</type>
+                               <label>Bonus Range</label>
+                               <description>Additional range vs. very sportive driver</description>
+                       </add-channel>
+                       <add-channel id="status-pos" groupIds="position">
+                               <type>mercedesme:status-pos</type>
+                               <label>Status Positioning</label>
+                       </add-channel>
+               </instruction-set>
        </thing-type>
 
        <thing-type uid="mercedesme:combustion">
                                <type>mercedesme:consumption-conv-unit</type>
                        </update-channel>
                </instruction-set>
+               <instruction-set targetVersion="2">
+                       <update-channel id="aux-heat" groupIds="hvac">
+                               <type>mercedesme:aux-heat</type>
+                               <label>Auxiliary Heating Control</label>
+                               <description>Switch on/off auxiliary heating</description>
+                       </update-channel>
+                       <add-channel id="aux-status" groupIds="hvac">
+                               <type>mercedesme:aux-status</type>
+                               <label>Auxiliary Heating Status</label>
+                               <description>Auxiliary heating status</description>
+                       </add-channel>
+                       <update-channel id="active-hvac" groupIds="hvac">
+                               <type>mercedesme:ac-status</type>
+                               <label>AC Precondition Control</label>
+                               <description>Switch on/off precondition air conditioning</description>
+                       </update-channel>
+                       <update-channel id="temperature-hvac" groupIds="hvac">
+                               <type>mercedesme:temperature-hvac</type>
+                               <label> AC Setpoint Temperature</label>
+                       </update-channel>
+                       <add-channel id="ac-status" groupIds="hvac">
+                               <type>mercedesme:ac-status</type>
+                               <label>AC Precondition Status</label>
+                               <description>Status of precondition air conditioning</description>
+                       </add-channel>
+                       <add-channel id="accel" groupIds="eco">
+                               <type>mercedesme:accel</type>
+                               <label>Acceleration Score</label>
+                               <description>Score for smooth acceleration</description>
+                       </add-channel>
+                       <add-channel id="coasting" groupIds="eco">
+                               <type>mercedesme:coasting</type>
+                               <label>Coasting Score</label>
+                               <description>Score for driving without braking</description>
+                       </add-channel>
+                       <add-channel id="constant" groupIds="eco">
+                               <type>mercedesme:constant</type>
+                               <label>Constant Score</label>
+                               <description>Score for driving with constant speed</description>
+                       </add-channel>
+                       <add-channel id="bonus" groupIds="eco">
+                               <type>mercedesme:bonus</type>
+                               <label>Bonus Range</label>
+                               <description>Additional range vs. very sportive driver</description>
+                       </add-channel>
+                       <add-channel id="status-pos" groupIds="position">
+                               <type>mercedesme:status-pos</type>
+                               <label>Status Positioning</label>
+                       </add-channel>
+               </instruction-set>
        </thing-type>
 
 </update:update-descriptions>
index ce2b93766d2138f6a87e5991cb07a1e596cc8486..92e5f009c0de581a4a71fb5bbbd8e28afc670afd 100644 (file)
@@ -16,6 +16,7 @@ import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.*;
 import static org.openhab.binding.mercedesme.internal.Constants.*;
 
+import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
 
@@ -37,6 +38,7 @@ import org.openhab.core.thing.ThingUID;
 import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
 import org.openhab.core.thing.link.ItemChannelLinkRegistry;
 import org.openhab.core.types.RefreshType;
+import org.openhab.core.types.UnDefType;
 
 import com.daimler.mbcarkit.proto.VehicleEvents.VEPUpdate;
 import com.daimler.mbcarkit.proto.Vehicleapi.AppTwinCommandStatus;
@@ -50,6 +52,34 @@ import com.daimler.mbcarkit.proto.Vehicleapi.AppTwinCommandStatusUpdatesByPID;
  */
 @NonNullByDefault
 class VehicleHandlerTest {
+    public static final int GROUP_COUNT = 12;
+
+    public static final int ECOSCORE_UPDATE_COUNT = 4;
+    public static final int HVAC_UPDATE_COUNT = 9;
+    public static final int POSITIONING_UPDATE_COUNT = 3;
+
+    private static final int EVENT_STORAGE_COUNT = HVAC_UPDATE_COUNT + POSITIONING_UPDATE_COUNT + ECOSCORE_UPDATE_COUNT
+            + 76;
+
+    public static Map<String, Object> createBEV() {
+        Thing thingMock = mock(Thing.class);
+        when(thingMock.getThingTypeUID()).thenReturn(Constants.THING_TYPE_BEV);
+        when(thingMock.getUID()).thenReturn(new ThingUID("test", Constants.BEV));
+        when(thingMock.getProperties()).thenReturn(Map.of(MB_KEY_COMMAND_CHARGE_PROGRAM_CONFIGURE, "true"));
+        AccountHandlerMock ahm = new AccountHandlerMock();
+        VehicleHandler vh = new VehicleHandler(thingMock, new LocationProviderMock(),
+                mock(MercedesMeCommandOptionProvider.class), mock(MercedesMeStateOptionProvider.class));
+        vh.accountHandler = Optional.of(ahm);
+        VehicleConfiguration vehicleConfig = new VehicleConfiguration();
+        vh.config = Optional.of(vehicleConfig);
+        ThingCallbackListener updateListener = new ThingCallbackListener();
+        vh.setCallback(updateListener);
+        Map<String, Object> instances = new HashMap<>();
+        instances.put(ThingCallbackListener.class.getCanonicalName(), updateListener);
+        instances.put(VehicleHandler.class.getCanonicalName(), vh);
+        instances.put(AccountHandlerMock.class.getCanonicalName(), ahm);
+        return instances;
+    }
 
     @Test
     public void testBEVFullUpdateNoCapacities() {
@@ -68,7 +98,7 @@ class VehicleHandlerTest {
         VEPUpdate update = ProtoConverter.json2Proto(json, true);
         vh.distributeContent(update);
 
-        assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
+        assertEquals(GROUP_COUNT, updateListener.updatesPerGroupMap.size(), "Group Update Count");
         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
         assertEquals(5, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
         assertEquals(8, updateListener.getUpdatesForGroup("windows"), "Windows Update Count");
@@ -76,10 +106,10 @@ class VehicleHandlerTest {
         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Tire Update Count");
         assertEquals(6, updateListener.getUpdatesForGroup("service"), "Service Update Count");
         assertEquals(7, updateListener.getUpdatesForGroup("range"), "Range Update Count");
-        assertEquals(2, updateListener.getUpdatesForGroup("position"), "Position Update Count");
+        assertEquals(POSITIONING_UPDATE_COUNT, updateListener.getUpdatesForGroup("position"), "Position Update Count");
         assertEquals(5, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
-        assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
-        assertEquals(10, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
+        assertEquals(HVAC_UPDATE_COUNT, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
+        assertEquals(12, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
     }
 
     @Test
@@ -104,7 +134,7 @@ class VehicleHandlerTest {
         VEPUpdate update = ProtoConverter.json2Proto(json, true);
         vh.distributeContent(update);
 
-        assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
+        assertEquals(GROUP_COUNT, updateListener.updatesPerGroupMap.size(), "Group Update Count");
         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
         assertEquals(5, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
         assertEquals(8, updateListener.getUpdatesForGroup("windows"), "Windows Update Count");
@@ -112,10 +142,14 @@ class VehicleHandlerTest {
         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Tire Update Count");
         assertEquals(6, updateListener.getUpdatesForGroup("service"), "Service Update Count");
         assertEquals(7, updateListener.getUpdatesForGroup("range"), "Range Update Count");
-        assertEquals(2, updateListener.getUpdatesForGroup("position"), "Position Update Count");
+        assertEquals(POSITIONING_UPDATE_COUNT, updateListener.getUpdatesForGroup("position"), "Position Update Count");
         assertEquals(5, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
-        assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
-        assertEquals(10, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
+        assertEquals(HVAC_UPDATE_COUNT, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
+        assertEquals(12, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
+        // Cable unplugged = 3
+        assertEquals("3", updateListener.getResponse("test::bev:charge#status").toFullString(), "Charge Error");
+        // No Error = 0
+        assertEquals("0", updateListener.getResponse("test::bev:charge#error").toFullString(), "Charge Error");
         assertTrue(updateListener.getResponse("test::bev:range#mileage").toFullString().endsWith("mi"),
                 "Mileague Unit");
         assertTrue(updateListener.getResponse("test::bev:range#range-electric").toFullString().endsWith("mi"),
@@ -158,7 +192,7 @@ class VehicleHandlerTest {
         VEPUpdate update = ProtoConverter.json2Proto(json, true);
         vh.distributeContent(update);
 
-        assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
+        assertEquals(GROUP_COUNT, updateListener.updatesPerGroupMap.size(), "Group Update Count");
         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
         assertEquals(5, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
         assertEquals(8, updateListener.getUpdatesForGroup("windows"), "Windows Update Count");
@@ -166,12 +200,16 @@ class VehicleHandlerTest {
         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Tire Update Count");
         assertEquals(6, updateListener.getUpdatesForGroup("service"), "Service Update Count");
         assertEquals(7, updateListener.getUpdatesForGroup("range"), "Range Update Count");
-        assertEquals(2, updateListener.getUpdatesForGroup("position"), "Position Update Count");
+        assertEquals(POSITIONING_UPDATE_COUNT, updateListener.getUpdatesForGroup("position"), "Position Update Count");
         assertEquals(5, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
-        assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
-        assertEquals(10, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
+        assertEquals(HVAC_UPDATE_COUNT, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
+        assertEquals(12, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
         assertEquals("2023-09-06 13:55", ((DateTimeType) updateListener.getResponse("test::bev:charge#end-time"))
                 .format("%1$tY-%1$tm-%1$td %1$tH:%1$tM"), "End of Charge Time");
+        // Charging = 0
+        assertEquals("0", updateListener.getResponse("test::bev:charge#status").toFullString(), "Charge Status");
+        // No Error = 0
+        assertEquals("0", updateListener.getResponse("test::bev:charge#error").toFullString(), "Charge Error");
     }
 
     @Test
@@ -286,7 +324,7 @@ class VehicleHandlerTest {
         VEPUpdate update = ProtoConverter.json2Proto(json, true);
         vh.distributeContent(update);
 
-        assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
+        assertEquals(GROUP_COUNT, updateListener.updatesPerGroupMap.size(), "Group Update Count");
         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
         assertEquals(5, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
         assertEquals(8, updateListener.getUpdatesForGroup("windows"), "Windows Update Count");
@@ -294,10 +332,10 @@ class VehicleHandlerTest {
         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Trip Update Count");
         assertEquals(8, updateListener.getUpdatesForGroup("service"), "Trip Update Count");
         assertEquals(14, updateListener.getUpdatesForGroup("range"), "Update Upadte Count");
-        assertEquals(2, updateListener.getUpdatesForGroup("position"), "Update Upadte Count");
+        assertEquals(POSITIONING_UPDATE_COUNT, updateListener.getUpdatesForGroup("position"), "Update Upadte Count");
         assertEquals(6, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
-        assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
-        assertEquals(7, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
+        assertEquals(HVAC_UPDATE_COUNT, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
+        assertEquals(9, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
     }
 
     @Test
@@ -348,7 +386,7 @@ class VehicleHandlerTest {
         VEPUpdate update = ProtoConverter.json2Proto(json, true);
         vh.distributeContent(update);
 
-        assertEquals(11, updateListener.updatesPerGroupMap.size(), "Group Update Count");
+        assertEquals(GROUP_COUNT, updateListener.updatesPerGroupMap.size(), "Group Update Count");
         assertEquals(10, updateListener.getUpdatesForGroup("doors"), "Doors Update Count");
         // 1 update more due to proto channel connected
         // assertEquals(6, updateListener.getUpdatesForGroup("vehicle"), "Vehcile Update Count");
@@ -357,18 +395,18 @@ class VehicleHandlerTest {
         assertEquals(10, updateListener.getUpdatesForGroup("tires"), "Tire Update Count");
         assertEquals(6, updateListener.getUpdatesForGroup("service"), "Service Update Count");
         assertEquals(7, updateListener.getUpdatesForGroup("range"), "Range Update Count");
-        assertEquals(2, updateListener.getUpdatesForGroup("position"), "Position Update Count");
+        assertEquals(POSITIONING_UPDATE_COUNT, updateListener.getUpdatesForGroup("position"), "Position Update Count");
         assertEquals(5, updateListener.getUpdatesForGroup("lock"), "Lock Update Count");
-        assertEquals(7, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
-        assertEquals(10, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
+        assertEquals(HVAC_UPDATE_COUNT, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
+        assertEquals(12, updateListener.getUpdatesForGroup("charge"), "Charge Update Count");
 
         /**
          * VehicleHandler fully updated eventStorage shall contain all data
          * Let's simulate an item ad causing a RefreshType command
          * Shall deliver data immediately
          */
-        assertEquals(83, vh.eventStorage.size());
-        assertEquals(83, updateListener.updatesReceived.size());
+        assertEquals(EVENT_STORAGE_COUNT, vh.eventStorage.size());
+        assertEquals(EVENT_STORAGE_COUNT, updateListener.updatesReceived.size());
         updateListener = new ThingCallbackListener();
         vh.setCallback(updateListener);
         ChannelUID mileageChannelUID = new ChannelUID(new ThingUID("test", Constants.BEV), Constants.GROUP_RANGE,
@@ -517,4 +555,65 @@ class VehicleHandlerTest {
             fail();
         }
     }
+
+    @Test
+    public void testPositioning() {
+        Map<String, Object> instances = createBEV();
+        ThingCallbackListener updateListener = (ThingCallbackListener) instances
+                .get(ThingCallbackListener.class.getCanonicalName());
+        VehicleHandler vHandler = (VehicleHandler) instances.get(VehicleHandler.class.getCanonicalName());
+        assertNotNull(updateListener);
+        assertNotNull(vHandler);
+
+        String json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-EQA.json");
+        VEPUpdate update = ProtoConverter.json2Proto(json, true);
+        vHandler.distributeContent(update);
+
+        assertEquals(POSITIONING_UPDATE_COUNT, updateListener.getUpdatesForGroup("position"), "Position Update Count");
+        assertEquals("1.23,4.56", updateListener.getResponse("test::bev:position#gps").toFullString(),
+                "Positioning GPS");
+        assertEquals("44.5 °", updateListener.getResponse("test::bev:position#heading").toFullString(),
+                "Positioning Heading");
+        assertEquals(5, ((DecimalType) updateListener.getResponse("test::bev:position#status")).intValue(),
+                "Positioning Status");
+    }
+
+    @Test
+    public void testHVAC() {
+        Map<String, Object> instances = createBEV();
+        ThingCallbackListener updateListener = (ThingCallbackListener) instances
+                .get(ThingCallbackListener.class.getCanonicalName());
+        VehicleHandler vHandler = (VehicleHandler) instances.get(VehicleHandler.class.getCanonicalName());
+        assertNotNull(updateListener);
+        assertNotNull(vHandler);
+
+        String json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-EQA.json");
+        VEPUpdate update = ProtoConverter.json2Proto(json, true);
+        vHandler.distributeContent(update);
+
+        assertEquals(HVAC_UPDATE_COUNT, updateListener.getUpdatesForGroup("hvac"), "HVAC Update Count");
+        assertEquals(0, ((DecimalType) updateListener.getResponse("test::bev:hvac#ac-status")).intValue(),
+                "AC Statuns");
+        assertEquals(UnDefType.UNDEF, updateListener.getResponse("test::bev:hvac#aux-status"), "Aux Heating Status");
+    }
+
+    @Test
+    public void testEcoScore() {
+        Map<String, Object> instances = createBEV();
+        ThingCallbackListener updateListener = (ThingCallbackListener) instances
+                .get(ThingCallbackListener.class.getCanonicalName());
+        VehicleHandler vHandler = (VehicleHandler) instances.get(VehicleHandler.class.getCanonicalName());
+        assertNotNull(updateListener);
+        assertNotNull(vHandler);
+
+        String json = FileReader.readFileInString("src/test/resources/proto-json/MB-BEV-EQA.json");
+        VEPUpdate update = ProtoConverter.json2Proto(json, true);
+        vHandler.distributeContent(update);
+
+        assertEquals("72 %", updateListener.getResponse("test::bev:eco#accel").toFullString(), "Eco Acceleration");
+        assertEquals("81 %", updateListener.getResponse("test::bev:eco#coasting").toFullString(), "Eco Coasting");
+        assertEquals("60 %", updateListener.getResponse("test::bev:eco#constant").toFullString(), "Eco Constant");
+        assertEquals("10.2 km", updateListener.getResponse("test::bev:eco#bonus").toFullString(), "Eco Bonus");
+        assertEquals(ECOSCORE_UPDATE_COUNT, updateListener.getUpdatesForGroup("eco"), "ECO Update Count");
+    }
 }
index cee4dbb265d49b28dd456993719daf8650703335..850049ab86bc9241b08a50651ca9c6506471a4cb 100644 (file)
@@ -71,7 +71,8 @@
                "chargeCouplerDCStatus",
                "chargeCouplerDCLockStatus",
                "chargingactive",
-               "chargingstatus",
+        "chargingstatus",
+        "chargingErrorDetails",
                "chargingPower",
                "endofchargetime",
                "chargePrograms",