Skip to content

Commit e1a4a65

Browse files
committed
[MQTT] support starting/stopping charging via setting drivetrain/charging
1 parent 5d6115b commit e1a4a65

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
### Added
99
- API
1010
- ASN.1 Types for `OTA_ChrgCtrlReq` and `OTA_ChrgCtrlStsResp`
11+
- MQTT
12+
- support starting/stopping charging via setting `drivetrain/charging`
1113

1214
### Changed
1315
- MQTT

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

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import net.heberling.ismart.asn1.v2_1.entity.OTA_RVMVehicleStatusReq;
2424
import net.heberling.ismart.asn1.v2_1.entity.OTA_RVMVehicleStatusResp25857;
2525
import net.heberling.ismart.asn1.v2_1.entity.RvcReqParam;
26+
import net.heberling.ismart.asn1.v3_0.Message;
27+
import net.heberling.ismart.asn1.v3_0.entity.OTA_ChrgCtrlReq;
28+
import net.heberling.ismart.asn1.v3_0.entity.OTA_ChrgCtrlStsResp;
2629
import net.heberling.ismart.asn1.v3_0.entity.OTA_ChrgMangDataResp;
2730
import org.bn.coders.IASN1PreparedElement;
2831
import org.eclipse.paho.client.mqttv3.IMqttClient;
@@ -345,6 +348,74 @@ private void sendCommand(byte type, SortedMap<Integer, byte[]> parameter)
345348
SaicMqttGateway.anonymized(otaRvcStatus25857MessageCoder, sendCommandReqestMessage)));
346349
}
347350

351+
private void sendCharging(boolean state)
352+
throws URISyntaxException,
353+
ExecutionException,
354+
InterruptedException,
355+
TimeoutException,
356+
MqttException,
357+
IOException {
358+
net.heberling.ismart.asn1.v3_0.MessageCoder<OTA_ChrgCtrlReq> otaRvcReqMessageCoder =
359+
new net.heberling.ismart.asn1.v3_0.MessageCoder<>(OTA_ChrgCtrlReq.class);
360+
361+
// we send a command end expect the car to wake up
362+
vehicleState.notifyCarActivityTime(ZonedDateTime.now(), false);
363+
364+
OTA_ChrgCtrlReq req = new OTA_ChrgCtrlReq();
365+
req.setTboxV2XReq(0);
366+
req.setTboxEleccLckCtrlReq(0);
367+
req.setChrgCtrlReq(state ? 1 : 2);
368+
369+
Message<OTA_ChrgCtrlReq> sendCommandRequest =
370+
otaRvcReqMessageCoder.initializeMessage(uid, token, vinInfo.getVin(), "516", 768, 7, req);
371+
372+
String sendCommandRequestMessage = otaRvcReqMessageCoder.encodeRequest(sendCommandRequest);
373+
374+
String sendCommandResponseMessage =
375+
Client.sendRequest(saicUri.resolve("/TAP.Web/ota.mpv30"), sendCommandRequestMessage);
376+
377+
final net.heberling.ismart.asn1.v3_0.MessageCoder<OTA_ChrgCtrlStsResp>
378+
otaRvcStatus25857MessageCoder =
379+
new net.heberling.ismart.asn1.v3_0.MessageCoder<>(OTA_ChrgCtrlStsResp.class);
380+
net.heberling.ismart.asn1.v3_0.Message<OTA_ChrgCtrlStsResp> sendCommandReqestMessage =
381+
otaRvcStatus25857MessageCoder.decodeResponse(sendCommandResponseMessage);
382+
383+
// ... use that to request the data again, until we have it
384+
// TODO: check for real errors (result!=0 and/or errorMessagePresent)
385+
while (sendCommandReqestMessage.getApplicationData() == null) {
386+
if (sendCommandReqestMessage.getBody().isErrorMessagePresent()) {
387+
if (sendCommandReqestMessage.getBody().getResult() == 2) {
388+
// TODO:
389+
// getBridgeHandler().relogin();
390+
}
391+
throw new TimeoutException(
392+
new String(sendCommandReqestMessage.getBody().getErrorMessage()));
393+
}
394+
SaicMqttGateway.fillReserved(sendCommandRequest.getReserved());
395+
396+
if (sendCommandReqestMessage.getBody().getResult() == 0) {
397+
// we get an eventId back...
398+
sendCommandRequest.getBody().setEventID(sendCommandReqestMessage.getBody().getEventID());
399+
} else {
400+
// try a fresh eventId
401+
sendCommandRequest.getBody().setEventID(0);
402+
}
403+
404+
sendCommandRequestMessage = otaRvcReqMessageCoder.encodeRequest(sendCommandRequest);
405+
406+
sendCommandResponseMessage =
407+
Client.sendRequest(saicUri.resolve("/TAP.Web/ota.mpv30"), sendCommandRequestMessage);
408+
409+
sendCommandReqestMessage =
410+
otaRvcStatus25857MessageCoder.decodeResponse(sendCommandResponseMessage);
411+
}
412+
413+
LOGGER.debug(
414+
"Got SendCommand Response message: {}",
415+
SaicMqttGateway.toJSON(
416+
SaicMqttGateway.anonymized(otaRvcStatus25857MessageCoder, sendCommandReqestMessage)));
417+
}
418+
348419
public void handleMQTTCommand(String topic, MqttMessage message) throws MqttException {
349420
try {
350421
if (message.isRetained()) {
@@ -363,6 +434,18 @@ public void handleMQTTCommand(String topic, MqttMessage message) throws MqttExce
363434
throw new MqttGatewayException("Unsupported payload " + message);
364435
}
365436
break;
437+
case DRIVETRAIN_CHARGING:
438+
switch (message.toString().toLowerCase()) {
439+
case "true":
440+
sendCharging(true);
441+
break;
442+
case "false":
443+
sendCharging(false);
444+
break;
445+
default:
446+
throw new MqttGatewayException("Unsupported payload " + message);
447+
}
448+
break;
366449
case CLIMATE_REMOTE_CLIMATE_STATE:
367450
switch (message.toString().toLowerCase()) {
368451
case "off":

0 commit comments

Comments
 (0)