Skip to content

Commit 1a981cd

Browse files
mschmiedeltisoft
authored andcommitted
Handle fallback for SOC when charge status update fails
Fixes #45
1 parent d7439c0 commit 1a981cd

File tree

3 files changed

+53
-29
lines changed

3 files changed

+53
-29
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- **Breaking** The default refresh rate while the car is active has been changed to 30 seconds
1717
- **Breaking** The default refresh rate while the car is inactive has been changed to 24 hours
1818
- support configuring `refresh/mode`, `refresh/period/active`, `refresh/period/inActive` and `refresh/period/inActiveGrace` via MQTT
19+
- Handle fallback for SOC when charge status update fails
20+
- API
21+
- Handle fallback for SOC when charge status update fails
1922

2023
### Fixed
2124
- MQTT

saic-java-client/src/main/java/net/heberling/ismart/abrp/ABRP.java

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.net.URLEncoder;
55
import java.nio.charset.StandardCharsets;
66
import java.util.HashMap;
7+
import java.util.Objects;
78
import java.util.stream.Collectors;
89
import net.heberling.ismart.asn1.v2_1.entity.OTA_RVMVehicleStatusResp25857;
910
import net.heberling.ismart.asn1.v3_0.entity.OTA_ChrgMangDataResp;
@@ -32,15 +33,30 @@ public static String updateAbrp(
3233
HashMap<String, Object> map = new HashMap<>();
3334
// utc [s]: Current UTC timestamp (epoch) in seconds (note, not milliseconds!)
3435
map.put("utc", vehicleStatus.getGpsPosition().getTimestamp4Short().getSeconds());
35-
// soc [SoC %]: State of Charge of the vehicle (what's displayed on the dashboard of
36-
// the vehicle is preferred)
37-
map.put("soc", chargeStatus.getBmsPackSOCDsp() / 10.d);
38-
// power [kW]: Instantaneous power output/input to the vehicle. Power output is
39-
// positive, power input is negative (charging)
40-
double current = chargeStatus.getBmsPackCrnt() * 0.05d - 1000.0d;
41-
double voltage = (double) chargeStatus.getBmsPackVol() * 0.25d;
42-
double power = current * voltage / 1000d;
43-
map.put("power", power);
36+
37+
if (Objects.nonNull(chargeStatus)) {
38+
// soc [SoC %]: State of Charge of the vehicle (what's displayed on the dashboard of
39+
// the vehicle is preferred)
40+
map.put("soc", chargeStatus.getBmsPackSOCDsp() / 10.d);
41+
// power [kW]: Instantaneous power output/input to the vehicle. Power output is
42+
// positive, power input is negative (charging)
43+
44+
// TODO: batt_temp [°C]: Battery temperature
45+
46+
double voltage = (double) chargeStatus.getBmsPackVol() * 0.25d;
47+
// voltage [V]: Battery pack voltage
48+
map.put("voltage", voltage);
49+
50+
double current = chargeStatus.getBmsPackCrnt() * 0.05d - 1000.0d;
51+
// current [A]: Battery pack current (similar to power: output is
52+
// positive, input (charging) is negative.)
53+
map.put("current", current);
54+
55+
double power = current * voltage / 1000d;
56+
map.put("power", power);
57+
} else {
58+
map.put("soc", vehicleStatus.getBasicVehicleStatus().getExtendedData1());
59+
}
4460
// speed [km/h]: Vehicle speed
4561
map.put("speed", vehicleStatus.getGpsPosition().getWayPoint().getSpeed() / 10.d);
4662
// lat [°]: Current vehicle latitude
@@ -80,12 +96,6 @@ public static String updateAbrp(
8096
if (vehicleStatus.getBasicVehicleStatus().getExteriorTemperature() != -128) {
8197
map.put("ext_temp", vehicleStatus.getBasicVehicleStatus().getExteriorTemperature());
8298
}
83-
// TODO: batt_temp [°C]: Battery temperature
84-
// voltage [V]: Battery pack voltage
85-
map.put("voltage", voltage);
86-
// current [A]: Battery pack current (similar to power: output is
87-
// positive, input (charging) is negative.)
88-
map.put("current", current);
8999
// odometer [km]: Current odometer reading in km.
90100
if (vehicleStatus.getBasicVehicleStatus().getMileage() > 0) {
91101
map.put("odometer", vehicleStatus.getBasicVehicleStatus().getMileage() / 10.d);

saic-java-mqtt-gateway/src/main/java/net/heberling/ismart/mqtt/VehicleHandler.java

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@
77
import java.net.URISyntaxException;
88
import java.nio.charset.StandardCharsets;
99
import java.time.ZonedDateTime;
10-
import java.util.ArrayList;
11-
import java.util.List;
12-
import java.util.Map;
13-
import java.util.SortedMap;
14-
import java.util.TreeMap;
10+
import java.util.*;
1511
import java.util.concurrent.ExecutionException;
1612
import java.util.concurrent.TimeoutException;
1713
import net.heberling.ismart.Client;
@@ -84,17 +80,17 @@ void handleVehicle() throws MqttException, IOException {
8480
OTA_ChrgMangDataResp chargeStatus = updateChargeStatus(uid, token, vinInfo.getVin());
8581
final String abrpApiKey = saicMqttGateway.getAbrpApiKey();
8682
final String abrpUserToken = saicMqttGateway.getAbrpUserToken(vinInfo.getVin());
87-
if (abrpApiKey != null
88-
&& abrpUserToken != null
89-
&& vehicleStatus != null
90-
&& chargeStatus != null) {
83+
if (abrpApiKey != null && abrpUserToken != null && vehicleStatus != null) {
9184
String abrpResponse =
9285
ABRP.updateAbrp(abrpApiKey, abrpUserToken, vehicleStatus, chargeStatus);
9386
MqttMessage msg = new MqttMessage(abrpResponse.getBytes(StandardCharsets.UTF_8));
9487
msg.setQos(0);
9588
msg.setRetained(true);
9689
client.publish(vehicleState.getMqttVINPrefix() + "/" + INTERNAL_ABRP, msg);
9790
}
91+
if (Objects.isNull(chargeStatus)) {
92+
updateFallbackChargeStateData(vehicleStatus);
93+
}
9894
vehicleState.markSuccessfulRefresh();
9995
LOGGER.info("Refreshing vehicle status succeeded...");
10096

@@ -113,6 +109,21 @@ void handleVehicle() throws MqttException, IOException {
113109
}
114110
}
115111

112+
private void updateFallbackChargeStateData(OTA_RVMVehicleStatusResp25857 vehicleStatus)
113+
throws MqttException {
114+
LOGGER.warn("Extracting SOC from vehicle status as charge state update failed...");
115+
MqttMessage msg =
116+
new MqttMessage(
117+
vehicleStatus
118+
.getBasicVehicleStatus()
119+
.getExtendedData1()
120+
.toString()
121+
.getBytes(StandardCharsets.UTF_8));
122+
msg.setQos(0);
123+
msg.setRetained(true);
124+
client.publish(vehicleState.getMqttVINPrefix() + "/" + DRIVETRAIN_SOC, msg);
125+
}
126+
116127
private OTA_RVMVehicleStatusResp25857 updateVehicleStatus(String uid, String token, String vin)
117128
throws IOException, MqttException {
118129
MessageCoder<OTA_RVMVehicleStatusReq> otaRvmVehicleStatusReqMessageCoder =
@@ -223,11 +234,11 @@ private OTA_ChrgMangDataResp updateChargeStatus(String uid, String token, String
223234
if (chargingStatusResponseMessage.getBody().getResult() == 2) {
224235
// TODO: relogn
225236
}
226-
throw new MqttGatewayException(
227-
"Refreshing Charging State from SAIC API failed with message: "
228-
+ new String(
229-
chargingStatusResponseMessage.getBody().getErrorMessage(),
230-
StandardCharsets.UTF_8));
237+
LOGGER.error(
238+
"Refreshing Charging State from SAIC API failed with message: {}",
239+
new String(
240+
chargingStatusResponseMessage.getBody().getErrorMessage(), StandardCharsets.UTF_8));
241+
return null;
231242
}
232243

233244
SaicMqttGateway.fillReserved(chargingStatusMessage.getReserved());

0 commit comments

Comments
 (0)