Getting started with the Fleet SDK

In this tutorial you'll find detailed instructions for getting started with the Fleet SDK. The Fleet SDK enables fleet owners to manage and consume data from their fleet of vehicles. The SDK is written in Kotlin and is fully compatible with Java 8 runtime server-side applications. Not using Java? You can integrate the fleet related APIs directly following the Fleet Clearance Tutorial.

Production only

Note that fleet clearance is currently only possible for production applications and is not yet supported by the car emulator. You will therefore need a verified production application in order to follow this tutorial.

Introduction and Setup

The distributed Java package name is hmkit-fleet and it's available on mavenCentral(). There is also a sample application that demonstrates the use of all SDK functions, which can be downloaded from the sample apps page.

Requirements

The SDK requires Java 8 to be installed.

Add the SDK to your project

Add the Fleet SDK to your build.gradle file. The hmkit-auto-api package is used to compose commands and to parse data responses.

implementation "com.high-mobility:hmkit-fleet:0.2"
implementation 'com.high-mobility:hmkit-auto-api:3.12.1'

Synchronise the Gradle project.

Create a Production Cloud App

In the Production tab you will find your apps for retrieving data from our live environment. In the app details page you are going to set the permissions it requires and manage its credentials. Let's see how to create a new app.

Heads up

Currently it's not possible to use the Fleet SDK with an app in the Develop section, which are connected to the car emulators.

  1. Go to the Production tab, click the big plus (+) button and select Cloud App. Enter a name and continue.
  2. Select the permissions that your app needs by clicking the "Select Permissions" button. Select the data points that you want to consume and hit "Save".
  3. Fill in all app information and click "Submit for review". Once done we will enable your application for live data access as soon as we have performed our app verification procedures. You will get notified as soon as it's done and it usually takes less than 48h.

Initialise the SDK

Already when the Cloud App has been created you can go ahead and get all the credentials you need in order to initialise the SDK. As the SDK simplifies the interaction with three different APIs, you will have to get credentials from three different sources, all of which are visible through the left menu on the Cloud App page. Here's a breakdown together with all the details.

1. Get the Client Certificate

The SDK uses a Client Certificate to identify the app towards our platform when sending telematics commands. You can find a pre-filled code snippet under the "Client Certificate" tab in the left menu. Just copy the "Java Fleet" snippet into your application code. In addition, the code snippet has placeholders for credentials that have to be inserted next.

ServiceAccountApiConfiguration configuration = new ServiceAccountApiConfiguration(
    "", // Add Service Account API Key here
    "", // Add Service Account Private Key here
    [CLIENT CERTIFICATE],
    [CLIENT PRIVATE KEY],
    "", // Add OAuth2 Client ID here
    ""  // Add OAuth2 Client Secret here
);
HMKitFleet.INSTANCE.setConfiguration(configuration);

2. Insert Service Account credentials

Next you will need to add an id and private key for the Service Account API. This API is used for queueing vehicles to be cleared for access and for checking the clearance status of each vehicle.

  1. Go to the "Service Account Keys" section in the menu to the left.
  2. Click on the plus (+) button. This will prompt you to download the credential as a JSON file.
  3. Open the JSON file on your computer and copy the id and private_key values into the snippet from the first step.

The downloaded Service Acccount API credential will look something like this:

{
  "inserted_at": "2021-03-18T10:34:21",
  "id": "83ffc724-d333-41c3-b09a-91a5961d4160",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGdd...[REDACTED].../zAqJAMd+vdZLRm\n-----END PRIVATE KEY-----"
}

3. Insert OAuth2 credentials

As the last step you'll need to insert the OAuth2 Client ID and Client Secret into the SDK initialisation snippet. The OAuth2 API is used to revoke vehicle access when you decide to no longer retrieve any data from a given vehicle.

  1. Go to the "OAuth Client" section in the menu to the left.
  2. Copy the Client ID and insert it into the snippet from the first step.
  3. Copy the Client Secret and insert it into the snippet as well.

With that you have all the arguments to initialise the SDK and it will manage the usage of the different APIs for you.

Helper image to find the credentials from the production cloud app menu:
Fleet SDK Credentials

Get clearance for vehicle

Before data can be retrieved for a vehicle, it has to be cleared for access. The clearance procedure is different for each carmaker and should be considered an asynchronous process. Clearing vehicles is done by passing in the Vehicle Identification Number (VIN). Multiple requests can be run in parallel.

Response<ClearanceStatus> response =
        hmkitFleet.requestClearance(vin, Brand.MERCEDES_BENZ).get();

if (response.getResponse() != null) {
    logger.info(format("requestClearances response: %s", response.getResponse()));
}
else {
    logger.info(format("requestClearances error: %s", response.getError().getTitle()));
}

The response will tell you if the vehicle was sucessfully queued for clearance.

Control Measure

For Mercedes-Benz vehicles, it's also necessary to pass in a control measure object with the current vehicle odometer reading. This value is verified with the actual odometer reading during the clearance procedure.

Here's an example of adding the odometer value as a control measure for a vehicle clearance request.

ControlMeasure measure = new Odometer(110000, Odometer.Length.KILOMETERS);
List<ControlMeasure> measures = List.of(measure);

Response<ClearanceStatus> response =
        hmkitFleet.requestClearance(vin, Brand.MERCEDES_BENZ, measures).get();

Get clearance statuses

Requesting clearance doesn't mean access to the vehicle just yet, as the clearance has to be approved first. The clearance status can be requested with getClearanceStatuses()

Response<List<ClearanceStatus>> response = hmkitFleet.getClearanceStatuses().get();

if (response.getResponse() != null) {
    logger.info(format("getClearanceStatuses response"));
    for (ClearanceStatus status : response.getResponse()) {
        logger.info(format("status: %s:%s",
                status.getVin(),
                status.getStatus()));
    }
} else {
    logger.info(format("getClearanceStatuses error: %s", response.getError().getTitle()));
}

Get Vehicle Access

After vehicle clearance status is APPROVED, the Vehicle Access object can be queried. This object is used to send Telematics Commands and later to revoke the vehicle access. The Vehicle Access object does not expire, and should thus be securely persisted by your application for later use.

// use the stored VehicleAccess if it exists
VehicleAccess storedVehicleAccess = vehicleAccessStore.read(vin);
if (storedVehicleAccess != null) return storedVehicleAccess;

// download VehicleAccess if it does not exist
Response<VehicleAccess> accessResponse = hmkitFleet.getVehicleAccess(vin).get();
if (accessResponse.getError() != null)
    throw new RuntimeException(accessResponse.getError().getDetail());

// store the downloaded vehicle access
VehicleAccess serverVehicleAccess = accessResponse.getResponse();
vehicleAccessStore.store(serverVehicleAccess);

return serverVehicleAccess;

Send a Telematics Command

With Vehicle Access having been secured, you can start sending telematics command for requesting data and also for remote commands if the manufacturer supports it. For instance, getting the vehicle speed requires the following 3 steps:

1) Compose the Auto API command

Command getVehicleSpeed = new Diagnostics.GetState(Diagnostics.PROPERTY_SPEED);

2) Send the command

Response<Bytes> response = hmkitFleet.sendCommand(
        getVehicleSpeed,
        vehicleAccess
).get();

if (response.getError() != null)
    throw new RuntimeException(response.getError().getTitle());

3) Resolve the response command from the server response

Command commandFromVehicle = CommandResolver.resolve(response.getResponse());

if (commandFromVehicle instanceof Diagnostics.State) {
    Diagnostics.State diagnostics = (Diagnostics.State) commandFromVehicle;
    logger.info(format(
            "Got diagnostics response: %s", 
                        diagnostics.getSpeed().getValue().getValue()));
}

It's of course also possible to fetch a large dataset in one request.

Auto API
Check out the Java/Kotlin Auto API code references for further details on how to use vehicle commands.

Revoke Vehicle Access

The Vehicle Access object is also used to revoke the clearance for a specific vehicle:

Response<Boolean> response = hmkitFleet.revokeClearance(vehicleAccess).get();

if (response.getError() != null) {
    logger.info(format("revokeClearance error: %s", 
                                                response.getError().getDetail()));
} else {
    logger.info(format("revokeClearance success"));
}

After successful request, the Vehicle Access object becomes invalid and should be deleted from the storage.