From 3ea5dbcdad7a92189d492f1f3e1489269b142636 Mon Sep 17 00:00:00 2001 From: James Hewitt Date: Sun, 18 Jul 2021 19:15:59 +0100 Subject: [PATCH] [volvooncall] Extend battery channels (#10991) * [volvooncall] Extend battery channels Add some convenience channels for charging status and handle the battery level carefully because the API can be misleading. Signed-off-by: James Hewitt-Thomas Signed-off-by: dw-8 --- CODEOWNERS | 2 +- .../org.openhab.binding.volvooncall/README.md | 6 +- .../doc/example.events.txt | 73 +++++++++++++++++++ .../internal/VolvoOnCallBindingConstants.java | 4 + .../volvooncall/internal/dto/HvBattery.java | 9 +++ .../volvooncall/internal/dto/Status.java | 2 +- .../internal/handler/VehicleHandler.java | 37 ++++++++++ .../main/resources/OH-INF/thing/vehicle.xml | 57 ++++++++++++--- 8 files changed, 176 insertions(+), 14 deletions(-) create mode 100644 bundles/org.openhab.binding.volvooncall/doc/example.events.txt diff --git a/CODEOWNERS b/CODEOWNERS index 7751f544c671..bd8485467bc6 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 aec0a5bc87ca..35de9da1529c 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 000000000000..5db8ec1a86ac --- /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 11e901eed9e4..a6ba30c13a30 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 373051b1d19e..71cf78d7fc2c 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 7c70f687277c..014c6ac95cfc 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 6f0a52828794..d8f23ef1d4b4 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 7318026ab3a5..6fc3a6b44f5e 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 status lock @@ -343,7 +347,7 @@ Switch - At least on bulb is reported as dead + At least one bulb is reported as dead alarm @@ -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) batterylevel String - + 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)