diff --git a/CODEOWNERS b/CODEOWNERS
index 7751f544c6717..bd8485467bc63 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -312,7 +312,7 @@
/bundles/org.openhab.binding.verisure/ @jannegpriv
/bundles/org.openhab.binding.vigicrues/ @clinique
/bundles/org.openhab.binding.vitotronic/ @steand
-/bundles/org.openhab.binding.volvooncall/ @clinique
+/bundles/org.openhab.binding.volvooncall/ @clinique @Jamstah
/bundles/org.openhab.binding.warmup/ @jamesmelville
/bundles/org.openhab.binding.weathercompany/ @mhilbush
/bundles/org.openhab.binding.weatherunderground/ @lolodomo
diff --git a/bundles/org.openhab.binding.volvooncall/README.md b/bundles/org.openhab.binding.volvooncall/README.md
index aec0a5bc87ca6..35de9da1529c9 100644
--- a/bundles/org.openhab.binding.volvooncall/README.md
+++ b/bundles/org.openhab.binding.volvooncall/README.md
@@ -80,9 +80,13 @@ Following channels are currently available:
| other#washerFluidLevel | Number | Washer fluid level | Normal / Low / VeryLow |
| other#serviceWarning | String | Warning if service is needed | |
| other#bulbFailure | Switch | ON if at least one bulb is reported as failed | |
-| battery#batteryLevel | Number:Dimensionless | Battery level | Only for Plugin hybrid / Twin Engine models |
+| battery#batteryLevel | Number:Dimensionless | Battery level | Only for Plugin hybrid / Twin Engine models. The binding reports undefined in situations where it knows the API is misleading. |
+| battery#batteryLevelRaw | Number:Dimensionless | Battery level | Only for Plugin hybrid / Twin Engine models. Raw figure from the API, can be misleading. |
| battery#batteryDistanceToEmpty | Number:Length | Distance until battery is empty | Only for Plugin hybrid / Twin Engine models |
| battery#chargeStatus | String | Charging status | Only for Plugin hybrid / Twin Engine models |
+| battery#chargeStatusCable | Switch | Is the cable plugged in | Only for Plugin hybrid / Twin Engine models |
+| battery#chargeStatusCharging | Switch | Is the car currently charging | Only for Plugin hybrid / Twin Engine models |
+| battery#chargeStatusFullyCharged | Switch | Is the car fully charged | Only for Plugin hybrid / Twin Engine models |
| battery#timeToHVBatteryFullyCharged | Number:Time | Time in minutes until the battery is fully charged | Only for Plugin hybrid / Twin Engine models |
| battery#chargingEnd | DateTime | Calculated time when the battery is fully charged | Only for Plugin hybrid / Twin Engine models |
| lasttrip#tripConsumption | Number:Volume | Last trip fuel consumption | |
diff --git a/bundles/org.openhab.binding.volvooncall/doc/example.events.txt b/bundles/org.openhab.binding.volvooncall/doc/example.events.txt
new file mode 100644
index 0000000000000..5db8ec1a86acc
--- /dev/null
+++ b/bundles/org.openhab.binding.volvooncall/doc/example.events.txt
@@ -0,0 +1,73 @@
+# Some events from openhab to see how the api responds over different charging events during a cycle.
+#
+# Using custom build from 2021-07-12 that added battery#batteryLevelRaw, battery#chargeStatusCharging,
+# battery#chargeStatusFullyCharged, battery#chargeStatusCable and added some additional processing to
+# battery#batteryLevel.
+
+
+# Started up, car was fully charged
+
+2021-07-12 16:31:56.706 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevelRaw' changed from NULL to 1
+2021-07-12 16:31:56.954 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevel' changed from NULL to 1
+2021-07-12 16:31:57.003 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Cable' changed from NULL to OFF
+2021-07-12 16:31:57.030 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Preclimatization' changed from NULL to OFF
+2021-07-12 16:31:57.098 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charged' changed from NULL to ON
+2021-07-12 16:31:57.183 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charging' changed from NULL to OFF
+2021-07-12 16:33:03.143 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_ChargeStatus' changed from NULL to CableNotPluggedInCar
+
+# Went out
+
+2021-07-12 17:03:06.526 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevel' changed from 100 % to 73 %
+2021-07-12 17:03:06.534 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevelRaw' changed from 100 % to 73 %
+2021-07-12 17:03:06.544 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charged' changed from ON to OFF
+
+# Drove home
+
+2021-07-12 18:23:13.529 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevel' changed from 73 % to 41 %
+2021-07-12 18:23:13.533 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevelRaw' changed from 73 % to 41 %
+
+# Plugged in car, charging is on a timer
+
+2021-07-12 21:13:26.479 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevel' changed from 41 % to UNDEF
+2021-07-12 21:13:26.494 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevelRaw' changed from 41 % to 100 %
+2021-07-12 21:13:26.497 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_ChargeStatus' changed from CableNotPluggedInCar to CablePluggedInCar_ChargingPaused
+2021-07-12 21:13:26.499 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Cable' changed from OFF to ON
+
+# Openhab restart
+
+2021-07-12 21:49:20.176 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevelRaw' changed from NULL to 1
+# I think this was from persistence? \/
+2021-07-12 21:49:20.587 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevel' changed from NULL to 0.41
+2021-07-12 21:49:20.682 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Cable' changed from NULL to ON
+2021-07-12 21:49:20.721 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Preclimatization' changed from NULL to OFF
+2021-07-12 21:49:20.858 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charged' changed from NULL to OFF
+2021-07-12 21:49:20.992 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charging' changed from NULL to OFF
+2021-07-12 21:50:26.351 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevel' changed from 0.41 to UNDEF
+2021-07-12 21:50:26.369 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_ChargeStatus' changed from NULL to CablePluggedInCar_ChargingPaused
+
+# Automatic charging started @ 00:30
+
+2021-07-13 00:30:39.391 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_ChargeStatus' changed from CablePluggedInCar_ChargingPaused to CablePluggedInCar_Charging
+2021-07-13 00:30:39.393 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charging' changed from OFF to ON
+
+# Automatic charging stopped (to see what happens) @ 01:00
+
+2021-07-13 01:00:41.458 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevel' changed from UNDEF to 53 %
+2021-07-13 01:00:41.460 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevelRaw' changed from 100 % to 53 %
+2021-07-13 01:00:41.462 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_ChargeStatus' changed from CablePluggedInCar_Charging to CablePluggedInCar_ChargingInterrupted
+2021-07-13 01:00:41.464 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charging' changed from ON to OFF
+
+# Automatic charging started again @ 01:30
+
+2021-07-13 01:30:43.532 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevel' changed from 53 % to 23 %
+2021-07-13 01:30:43.535 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevelRaw' changed from 53 % to 23 %
+2021-07-13 01:30:43.537 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_ChargeStatus' changed from CablePluggedInCar_ChargingInterrupted to CablePluggedInCar_Charging
+2021-07-13 01:30:43.539 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charging' changed from OFF to ON
+2021-07-13 03:50:53.485 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevel' changed from 23 % to 100 %
+2021-07-13 03:50:53.488 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_BatteryLevelRaw' changed from 23 % to 100 %
+2021-07-13 03:50:53.490 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_ChargeStatus' changed from CablePluggedInCar_Charging to CablePluggedInCar_FullyCharged
+2021-07-13 03:50:53.493 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charging' changed from ON to OFF
+2021-07-13 03:50:53.495 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Car_Charged' changed from OFF to ON
+
+# Automatic charging stopped again @ 04:30
+
diff --git a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/VolvoOnCallBindingConstants.java b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/VolvoOnCallBindingConstants.java
index 11e901eed9e47..a6ba30c13a300 100644
--- a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/VolvoOnCallBindingConstants.java
+++ b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/VolvoOnCallBindingConstants.java
@@ -78,8 +78,12 @@ public class VolvoOnCallBindingConstants {
public static final String AVERAGE_SPEED = "averageSpeed";
public static final String SERVICE_WARNING = "serviceWarningStatus";
public static final String BATTERY_LEVEL = "batteryLevel";
+ public static final String BATTERY_LEVEL_RAW = "batteryLevelRaw";
public static final String BATTERY_DISTANCE_TO_EMPTY = "batteryDistanceToEmpty";
public static final String CHARGE_STATUS = "chargeStatus";
+ public static final String CHARGE_STATUS_CABLE = "chargeStatusCable";
+ public static final String CHARGE_STATUS_CHARGING = "chargeStatusCharging";
+ public static final String CHARGE_STATUS_FULLY_CHARGED = "chargeStatusFullyCharged";
public static final String TIME_TO_BATTERY_FULLY_CHARGED = "timeToHVBatteryFullyCharged";
public static final String CHARGING_END = "chargingEnd";
public static final String BULB_FAILURE = "bulbFailure";
diff --git a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/dto/HvBattery.java b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/dto/HvBattery.java
index 373051b1d19e0..71cf78d7fc2cf 100644
--- a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/dto/HvBattery.java
+++ b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/dto/HvBattery.java
@@ -27,8 +27,17 @@
public class HvBattery {
public int hvBatteryLevel = UNDEFINED;
public int distanceToHVBatteryEmpty = UNDEFINED;
+ /**
+ * Observed values:
+ * - CableNotPluggedInCar
+ * - CablePluggedInCar_ChargingPaused
+ * - CablePluggedInCar_Charging
+ * - CablePluggedInCar_ChargingInterrupted
+ * - CablePluggedInCar_FullyCharged
+ */
public @NonNullByDefault({}) StringType hvBatteryChargeStatusDerived;
public int timeToHVBatteryFullyCharged = UNDEFINED;
+
/*
* Currently unused in the binding, maybe interesting in the future
* private ZonedDateTime timestamp;
diff --git a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/dto/Status.java b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/dto/Status.java
index 7c70f687277cc..014c6ac95cfca 100644
--- a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/dto/Status.java
+++ b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/dto/Status.java
@@ -25,7 +25,7 @@
/**
* The {@link Status} is responsible for storing
- * Door Status informations returned by vehicule status rest answer
+ * Status information returned by vehicle status rest answer
*
* @author Gaƫl L'hopital - Initial contribution
*/
diff --git a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/handler/VehicleHandler.java
index 6f0a52828794a..d8f23ef1d4b47 100644
--- a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/handler/VehicleHandler.java
+++ b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/handler/VehicleHandler.java
@@ -373,6 +373,22 @@ private State getHeaterValue(String channelId, Heater heater) {
private State getBatteryValue(String channelId, HvBattery hvBattery) {
switch (channelId) {
case BATTERY_LEVEL:
+ /*
+ * If the car is charging the battery level can be reported as 100% by the API regardless of actual
+ * charge level, but isn't always. So, if we see that the car is Charging, ChargingPaused, or
+ * ChargingInterrupted and the reported battery level is 100%, then instead produce UNDEF.
+ *
+ * If we see FullyCharged, then we can rely on the value being 100% anyway.
+ */
+ if (hvBattery.hvBatteryChargeStatusDerived != null
+ && hvBattery.hvBatteryChargeStatusDerived.toString().startsWith("CablePluggedInCar_Charging")
+ && hvBattery.hvBatteryLevel != UNDEFINED && hvBattery.hvBatteryLevel == 100) {
+ return UnDefType.UNDEF;
+ } else {
+ return hvBattery.hvBatteryLevel != UNDEFINED ? new QuantityType<>(hvBattery.hvBatteryLevel, PERCENT)
+ : UnDefType.UNDEF;
+ }
+ case BATTERY_LEVEL_RAW:
return hvBattery.hvBatteryLevel != UNDEFINED ? new QuantityType<>(hvBattery.hvBatteryLevel, PERCENT)
: UnDefType.UNDEF;
case BATTERY_DISTANCE_TO_EMPTY:
@@ -382,6 +398,27 @@ private State getBatteryValue(String channelId, HvBattery hvBattery) {
case CHARGE_STATUS:
return hvBattery.hvBatteryChargeStatusDerived != null ? hvBattery.hvBatteryChargeStatusDerived
: UnDefType.UNDEF;
+ case CHARGE_STATUS_CABLE:
+ return hvBattery.hvBatteryChargeStatusDerived != null
+ ? OnOffType.from(
+ hvBattery.hvBatteryChargeStatusDerived.toString().startsWith("CablePluggedInCar_"))
+ : UnDefType.UNDEF;
+ case CHARGE_STATUS_CHARGING:
+ return hvBattery.hvBatteryChargeStatusDerived != null
+ ? OnOffType.from(hvBattery.hvBatteryChargeStatusDerived.toString().endsWith("_Charging"))
+ : UnDefType.UNDEF;
+ case CHARGE_STATUS_FULLY_CHARGED:
+ /*
+ * If the car is charging the battery level can be reported incorrectly by the API, so use the charging
+ * status instead of checking the level when the car is plugged in.
+ */
+ if (hvBattery.hvBatteryChargeStatusDerived != null
+ && hvBattery.hvBatteryChargeStatusDerived.toString().startsWith("CablePluggedInCar_")) {
+ return OnOffType.from(hvBattery.hvBatteryChargeStatusDerived.toString().endsWith("_FullyCharged"));
+ } else {
+ return hvBattery.hvBatteryLevel != UNDEFINED ? OnOffType.from(hvBattery.hvBatteryLevel == 100)
+ : UnDefType.UNDEF;
+ }
case TIME_TO_BATTERY_FULLY_CHARGED:
return hvBattery.timeToHVBatteryFullyCharged != UNDEFINED
? new QuantityType<>(hvBattery.timeToHVBatteryFullyCharged, MINUTE)
diff --git a/bundles/org.openhab.binding.volvooncall/src/main/resources/OH-INF/thing/vehicle.xml b/bundles/org.openhab.binding.volvooncall/src/main/resources/OH-INF/thing/vehicle.xml
index 7318026ab3a50..6fc3a6b44f5ec 100644
--- a/bundles/org.openhab.binding.volvooncall/src/main/resources/OH-INF/thing/vehicle.xml
+++ b/bundles/org.openhab.binding.volvooncall/src/main/resources/OH-INF/thing/vehicle.xml
@@ -210,13 +210,17 @@
+
-
+
+
+
+
-
+
@@ -237,7 +241,7 @@
Contact
-
+
Indicates if the window is opened
@@ -251,7 +255,7 @@
Number:Speed
-
+
Average speed of the vehicle
@@ -316,7 +320,7 @@
Switch
- Car locking status
+ Lock statuslock
@@ -343,7 +347,7 @@
Switch
- At least on bulb is reported as dead
+ At least one bulb is reported as deadalarm
@@ -364,7 +368,7 @@
Number
-
+
alarm
@@ -377,7 +381,7 @@
String
- Is car service needed ?
+ Is a car service needed?alarm
@@ -385,21 +389,52 @@
Number:Dimensionless
- Indicates the level of power in the battery (in case of PHEV / Twin Engine)
+ Indicates the level of power in the battery, or unknown in situations the API is misleading (in case of
+ PHEV / Twin Engine)
+ batterylevel
+
+
+
+
+ Number:Dimensionless
+
+ Indicates the level of power in the battery taken straight from the API, which can be misleading (in case
+ of PHEV / Twin Engine)batterylevelString
-
+
Status of charging (in case of PHEV / Twin Engine)
+
+ Switch
+
+ Indicates if the charging cable is connected
+
+
+
+
+ Switch
+
+ Indicates if the car is currently charging
+
+
+
+
+ Switch
+
+ Indicates if the car is fully charged
+
+
+
Number:Time
-
+
Time in seconds until the battery is fully charged (in case of PHEV / Twin Engine)