| tank#distanceToEmpty | Number:Length | Distance till tank is empty | |
| position#location | Location | Location of the car | |
| position#locationTimestamp | DateTime | Timestamp of the latest confirmed location | |
-| tyrePressure#frontLeftTyre | String | Tyrepressure front left tyre | Normal / LowSoft |
-| tyrePressure#frontRightTyr | String | Tyrepressure front right tyre | Normal / LowSoft |
-| tyrePressure#rearLeftTyre | String | Tyrepressure rear left tyre | Normal / LowSoft |
-| tyrePressure#rearRightTyre | String | Tyrepressure rear right tyre | Normal / LowSoft |
+| tyrePressure#frontLeftTyre | Number | Tyrepressure front left tyre | Normal / LowSoft |
+| tyrePressure#frontRightTyre | Number | Tyrepressure front right tyre | Normal / LowSoft |
+| tyrePressure#rearLeftTyre | Number | Tyrepressure rear left tyre | Normal / LowSoft |
+| tyrePressure#rearRightTyre | Number | Tyrepressure rear right tyre | Normal / LowSoft |
| other#averageSpeed | Number:Speed | Average speed | |
| other#engineRunning | Switch | Is the car engine running | |
| other#remoteHeater | Switch | Start the car remote heater | Only if property 'remoteHeater' is true (see thing properties above) |
| other#preclimatization | Switch | Start the car preclimatization | Only if property 'preclimatization' is true (see thing properties above) |
-| other#brakeFluidLevel | String | Brake fluid level | Normal / Low / VeryLow |
-| other#washerFluidLevel | String | Washer fluid level | Normal / Low / VeryLow |
+| other#brakeFluidLevel | Number | Brake fluid level | Normal / Low / VeryLow |
+| 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 |
Number:Length Voc_Odometer "Kilométrage [%d %unit%]" (gVoc) {channel="volvooncall:vehicle:glh:XC60:odometer#odometer"}
Number:Dimensionless Voc_FuelLevel "Fuel Level" <sewerage> (gVoc) {channel="volvooncall:vehicle:glh:XC60:tank#fuelLevel"}
Switch Voc_Fuel_Alert "Niveau Carburant" <siren> (gVoc) {channel="volvooncall:vehicle:glh:XC60:tank#fuelAlert"}
-String Voc_Fluid_Message "Lave Glace" (gVoc) {channel="volvooncall:vehicle:glh:XC60:other#washerFluidLevel"}
+Number Voc_Fluid_Message "Lave Glace" (gVoc) {channel="volvooncall:vehicle:glh:XC60:other#washerFluidLevel"}
Location Voc_Location "Location" (gVoc) {channel="volvooncall:vehicle:glh:XC60:position#location"}
DateTime Voc_Location_LUD "Timestamp [%1$tH:%1$tM]" <time> (gVoc) {channel="volvooncall:vehicle:glh:XC60:position#locationTimestamp"}
Switch Voc_Fluid_Alert "Alerte Lave Glace" <siren> (gVoc)
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.library.types.OnOffType;
+import com.google.gson.annotations.SerializedName;
+
/**
* The {@link Status} is responsible for storing
* Door Status informations returned by vehicule status rest answer
*/
@NonNullByDefault
public class Status extends VocAnswer {
+ public enum FluidLevel {
+ @SerializedName("Normal")
+ NORMAL,
+ @SerializedName("Low")
+ LOW,
+ @SerializedName("VeryLow")
+ VERY_LOW,
+ UNKNOWN;
+ }
+
public double averageFuelConsumption = UNDEFINED;
public int averageSpeed = UNDEFINED;
public int fuelAmount = UNDEFINED;
private @Nullable OnOffType carLocked;
private @Nullable OnOffType engineRunning;
- public String brakeFluid = "";
- public String washerFluidLevel = "";
+ @SerializedName("brakeFluid")
+ public FluidLevel brakeFluidLevel = FluidLevel.UNKNOWN;
+ public FluidLevel washerFluidLevel = FluidLevel.UNKNOWN;
private @Nullable WindowsStatus windows;
private @Nullable DoorsStatus doors;
private @Nullable TyrePressure tyrePressure;
private @NonNullByDefault({}) List<Object> bulbFailures;
public Optional<WindowsStatus> getWindows() {
- WindowsStatus windows = this.windows;
- if (windows != null) {
- return Optional.of(windows);
- }
- return Optional.empty();
+ return Optional.ofNullable(windows);
}
public Optional<DoorsStatus> getDoors() {
- DoorsStatus doors = this.doors;
- if (doors != null) {
- return Optional.of(doors);
- }
- return Optional.empty();
+ return Optional.ofNullable(doors);
}
public Optional<TyrePressure> getTyrePressure() {
- TyrePressure tyrePressure = this.tyrePressure;
- if (tyrePressure != null) {
- return Optional.of(tyrePressure);
- }
- return Optional.empty();
+ return Optional.ofNullable(tyrePressure);
}
public Optional<HvBattery> getHvBattery() {
- HvBattery hvBattery = this.hvBattery;
- if (hvBattery != null) {
- return Optional.of(hvBattery);
- }
- return Optional.empty();
+ return Optional.ofNullable(hvBattery);
}
public Optional<Heater> getHeater() {
- Heater heater = this.heater;
- if (heater != null) {
- return Optional.of(heater);
- }
- return Optional.empty();
+ return Optional.ofNullable(heater);
}
public Optional<OnOffType> getCarLocked() {
- OnOffType carLocked = this.carLocked;
- if (carLocked != null) {
- return Optional.of(carLocked);
- }
- return Optional.empty();
+ return Optional.ofNullable(carLocked);
}
public Optional<OnOffType> getEngineRunning() {
- OnOffType engineRunning = this.engineRunning;
- if (engineRunning != null) {
- return Optional.of(engineRunning);
- }
- return Optional.empty();
+ return Optional.ofNullable(engineRunning);
}
public boolean aFailedBulb() {
package org.openhab.binding.volvooncall.internal.dto;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.core.library.types.StringType;
+
+import com.google.gson.annotations.SerializedName;
/**
* The {@link TyrePressure} is responsible for storing
*/
@NonNullByDefault
public class TyrePressure {
- public @NonNullByDefault({}) StringType frontLeftTyrePressure;
- public @NonNullByDefault({}) StringType frontRightTyrePressure;
- public @NonNullByDefault({}) StringType rearLeftTyrePressure;
- public @NonNullByDefault({}) StringType rearRightTyrePressure;
+
+ public enum PressureLevel {
+ @SerializedName("Normal")
+ NORMAL,
+ @SerializedName("LowSoft")
+ LOW_SOFT,
+ UNKNOWN;
+ }
+
+ public PressureLevel frontLeftTyrePressure = PressureLevel.UNKNOWN;
+ public PressureLevel frontRightTyrePressure = PressureLevel.UNKNOWN;
+ public PressureLevel rearLeftTyrePressure = PressureLevel.UNKNOWN;
+ public PressureLevel rearRightTyrePressure = PressureLevel.UNKNOWN;
+
/*
* Currently unused in the binding, maybe interesting in the future
* private ZonedDateTime timestamp;
import org.openhab.binding.volvooncall.internal.dto.Position;
import org.openhab.binding.volvooncall.internal.dto.PostResponse;
import org.openhab.binding.volvooncall.internal.dto.Status;
+import org.openhab.binding.volvooncall.internal.dto.Status.FluidLevel;
import org.openhab.binding.volvooncall.internal.dto.Trip;
import org.openhab.binding.volvooncall.internal.dto.TripDetail;
import org.openhab.binding.volvooncall.internal.dto.Trips;
import org.openhab.binding.volvooncall.internal.dto.TyrePressure;
+import org.openhab.binding.volvooncall.internal.dto.TyrePressure.PressureLevel;
import org.openhab.binding.volvooncall.internal.dto.Vehicles;
import org.openhab.binding.volvooncall.internal.dto.WindowsStatus;
import org.openhab.binding.volvooncall.internal.wrapper.VehiclePositionWrapper;
return UnDefType.NULL;
}
+ private State pressureLevelToState(PressureLevel level) {
+ return level != PressureLevel.UNKNOWN ? new DecimalType(level.ordinal()) : UnDefType.UNDEF;
+ }
+
private State getTyresValue(String channelId, TyrePressure tyrePressure) {
switch (channelId) {
case REAR_RIGHT_TYRE:
- return tyrePressure.rearRightTyrePressure;
+ return pressureLevelToState(tyrePressure.rearRightTyrePressure);
case REAR_LEFT_TYRE:
- return tyrePressure.rearLeftTyrePressure;
+ return pressureLevelToState(tyrePressure.rearLeftTyrePressure);
case FRONT_RIGHT_TYRE:
- return tyrePressure.frontRightTyrePressure;
+ return pressureLevelToState(tyrePressure.frontRightTyrePressure);
case FRONT_LEFT_TYRE:
- return tyrePressure.frontLeftTyrePressure;
+ return pressureLevelToState(tyrePressure.frontLeftTyrePressure);
}
return UnDefType.NULL;
}
case ENGINE_RUNNING:
return status.getEngineRunning().map(State.class::cast).orElse(UnDefType.UNDEF);
case BRAKE_FLUID_LEVEL:
- return new StringType(status.brakeFluid);
+ return fluidLevelToState(status.brakeFluidLevel);
case WASHER_FLUID_LEVEL:
- return new StringType(status.washerFluidLevel);
+ return fluidLevelToState(status.washerFluidLevel);
case AVERAGE_SPEED:
return status.averageSpeed != UNDEFINED ? new QuantityType<>(status.averageSpeed, KILOMETRE_PER_HOUR)
: UnDefType.UNDEF;
return UnDefType.NULL;
}
+ private State fluidLevelToState(FluidLevel level) {
+ return level != FluidLevel.UNKNOWN ? new DecimalType(level.ordinal()) : UnDefType.UNDEF;
+ }
+
private State getTankValue(String channelId, Status status) {
switch (channelId) {
case DISTANCE_TO_EMPTY:
ApiBridgeConfiguration configuration = getConfigAs(ApiBridgeConfiguration.class);
try {
- api = new VocHttpApi(configuration, gson, httpClient);
- CustomerAccounts account = api.getURL("customeraccounts/", CustomerAccounts.class);
+ VocHttpApi vocApi = new VocHttpApi(configuration, gson, httpClient);
+ CustomerAccounts account = vocApi.getURL("customeraccounts/", CustomerAccounts.class);
if (account.username != null) {
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, account.username);
+ this.api = vocApi;
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Incorrect login credentials");
}
@Override
public void dispose() {
- if (api != null) {
+ VocHttpApi vocApi = this.api;
+ if (vocApi != null) {
try {
- api.dispose();
+ vocApi.dispose();
api = null;
} catch (Exception e) {
logger.warn("Unable to stop VocHttpApi : {}", e.getMessage());
# binding
binding.volvooncall.name = Extension VolvoOnCall
-binding.volvooncall.description = Cette extension fournit l'accès aux services de Volvo On Call.
+binding.volvooncall.description = Cette extension fournit l'accès aux services de Volvo On Call.
# thing types
thing-type.volvooncall.vocapi.label = API Volvo On Call
-thing-type.volvooncall.vocapi.description = Fournit l'interface avec le service en ligne Volvo On Call. Pour recevoir les données, vous devez vous munir de vos informations de connection (nom d'utilisateur, mot de passe).
+thing-type.volvooncall.vocapi.description = Fournit l'interface avec le service en ligne Volvo On Call. Pour recevoir les données, vous devez vous munir de vos informations de connection (nom d'utilisateur, mot de passe).
-thing-type.volvooncall.vehicle.label = Véhicule
-thing-type.volvooncall.vehicle.description = Toutes les informations disponibles sur le véhicule Volvo.
+thing-type.volvooncall.vehicle.label = Véhicule
+thing-type.volvooncall.vehicle.description = Toutes les informations disponibles sur le véhicule Volvo.
+
+channel-type.volvooncall.fluidLevel.state.options.0=Normal
+channel-type.volvooncall.fluidLevel.state.options.1=Bas
+channel-type.volvooncall.fluidLevel.state.options.2=Très bas
<channel id="engineRunning" typeId="engineRunning"/>
<channel id="remoteHeater" typeId="remoteHeater"/>
<channel id="preclimatization" typeId="preclimatization"/>
- <channel id="brakeFluidLevel" typeId="brakeFluidLevel"/>
- <channel id="washerFluidLevel" typeId="washerFluidLevel"/>
+ <channel id="brakeFluidLevel" typeId="fluidLevel">
+ <label>Brake Fluid Level</label>
+ <description>Level of available brake fluid quantity.</description>
+ </channel>
+ <channel id="washerFluidLevel" typeId="fluidLevel">
+ <label>Washer Fluid Level</label>
+ <description>Level of available washer fluid quantity.</description>
+ </channel>
<channel id="serviceWarningStatus" typeId="serviceWarningStatus"/>
<channel id="bulbFailure" typeId="bulbFailure"/>
<channel id="carEvent" typeId="carEvent"/>
<channel-type id="fuelQuantity">
<item-type>Number:Volume</item-type>
<label>Fuel Quantity</label>
+ <category>oil</category>
<state pattern="%.2f %unit%" readOnly="true"></state>
</channel-type>
<item-type>Number:Dimensionless</item-type>
<label>Fuel Level</label>
<description>Indicates the level of fuel in the tank</description>
+ <category>oil</category>
<state pattern="%d %unit%" readOnly="true"></state>
</channel-type>
<item-type>Number</item-type>
<label>Average Consumption</label>
<description>Indicates the average fuel consumption in l/100km</description>
+ <category>chart</category>
<state pattern="%.1f l/100km" readOnly="true"></state>
</channel-type>
<item-type>DateTime</item-type>
<label>Timestamp</label>
<description>Data timestamp</description>
+ <category>time</category>
<state readOnly="true"/>
</channel-type>
<item-type>Switch</item-type>
<label>Locked</label>
<description>Car locking status</description>
+ <category>lock</category>
</channel-type>
<channel-type id="engineRunning">
<item-type>Switch</item-type>
<label>Preclimatization</label>
<description>Starts pre-climatization</description>
+ <category>heating</category>
</channel-type>
<channel-type id="remoteHeater">
<item-type>Switch</item-type>
<label>Remote Heater</label>
<description>(De)Activates remote heater</description>
+ <category>heating</category>
</channel-type>
<channel-type id="bulbFailure">
<item-type>Switch</item-type>
<label>Bulb Failure</label>
<description>At least on bulb is reported as dead</description>
+ <category>alarm</category>
<state readOnly="true"></state>
</channel-type>
- <channel-type id="brakeFluidLevel">
- <item-type>String</item-type>
- <label>Brake Fluid</label>
- <description>“VeryLow”,"Low", "Normal"</description>
- <state readOnly="true"></state>
- </channel-type>
-
- <channel-type id="washerFluidLevel">
- <item-type>String</item-type>
- <label>Washer Fluid</label>
- <description>“VeryLow”,"Low", "Normal"</description>
- <state readOnly="true"></state>
+ <channel-type id="fluidLevel">
+ <item-type>Number</item-type>
+ <label>Fluid Level</label>
+ <description>Level of available fluid quantity.</description>
+ <category>alarm</category>
+ <state readOnly="true">
+ <options>
+ <option value="0">Normal</option>
+ <option value="1">Low</option>
+ <option value="2">Very Low</option>
+ </options>
+ </state>
</channel-type>
<channel-type id="tyrePressure">
- <item-type>String</item-type>
+ <item-type>Number</item-type>
<label>Tyre pressure</label>
- <description>“LowSoft”, "Normal"</description>
- <state readOnly="true"></state>
+ <category>alarm</category>
+ <state readOnly="true">
+ <options>
+ <option value="0">Normal</option>
+ <option value="1">Low Soft</option>
+ </options>
+ </state>
</channel-type>
<channel-type id="serviceWarningStatus">
<item-type>String</item-type>
<label>Service Warning</label>
<description>Is car service needed ?</description>
+ <category>alarm</category>
<state readOnly="true"></state>
</channel-type>
<item-type>Number:Dimensionless</item-type>
<label>Battery Level</label>
<description>Indicates the level of power in the battery (in case of PHEV / Twin Engine)</description>
+ <category>batterylevel</category>
<state pattern="%d %unit%" readOnly="true"></state>
</channel-type>
<channel-type id="fuelAlert">
<item-type>Switch</item-type>
<label>Fuel Alarm</label>
- <description>set to 'ON' when the tank level is low</description>
+ <description>Set to 'ON' when the tank level is low</description>
+ <category>alarm</category>
<state readOnly="true"/>
</channel-type>