Skip to content

highmobility/auto-api-java

Repository files navigation

HMKit Auto API

This repository contains the java parsers for Auto API.

Dependencies

  • hmkit-utils

Install

Releases are pushed to mavenCentral. To include hmkit-auto-api in your project, add to build.gradle:

repositories {
  mavenCentral()
}

dependencies {
  implementation('com.high-mobility:hmkit-auto-api:{version}')
}

SLF4J is used for logging. Add slf4j binding to see the logs, for example:

implementation 'org.slf4j:slf4j-simple:1.8.0-beta1'

Find the latest version name in mavenCentral

How to create/parse commands

Find the command name in auto api doc, then locate a class in com.highmobility.autoapi package with the same name. Every command has a designated class and it is used for all of the common use cases:

Parse the received command's bytes

byte[] bytes = ...
Command command = CommandResolver.resolve(bytes);

VehicleStatus vehicleStatus;
Capabilities capabilities;

if (command instanceof VehicleStatus) {
    vehicleStatus = (VehicleStatus) command;
}
else if (command instanceof Capabilities) {
    capabilities = (Capabilities) command;
}

Get a specific state from the vehicle status

LockState state = vehicleStatus.getState(LockState.TYPE);
if (state != null) {
    ...
}

Inspect whether the capability is supported for the vehicle

if (capabilities.isSupported(LockState.TYPE)) {
    ...
}

Send a command

Bytes commandBytes = new LockUnlockDoors(Lock.LOCKED).getBytes();
sendCommand(commandBytes)

Get a capability

Bytes commandBytes = new GetCapability(SendHeartRate.TYPE).getBytes();
sendCommand(commandBytes)

Check for the failed command's type

Failure failure;
if (command instanceof Failure) {
    failure = (Failure)command;
    if (failure.getFailedType != null && failure.getFailedType.equals(LockUnlockDoors.TYPE) {
        // the lock unlock command failed
    }
}

Builders for bigger commands(states)

Builder pattern is used to build commands with more properties, for example Vehicle status:

// create the builder
VehicleStatus.Builder builder = new VehicleStatus.Builder();
// add known properties as simple values 
builder.setVin(new Property("JF2SHBDC7CH451869"));
builder.setPowerTrain(new Property(PowerTrain.ALLELECTRIC));;
builder.setModelYear(new Property(2017));
//        builder.setPower(220);
// can also add unknown properties
builder.addProperty(new Property(220));
// can chain the properties adding
builder.setNumberOfDoors(new Property(5)).setNumberOfSeats(new Property(5));

// use builders from other commands to append them to vehicle status
TrunkState.Builder trunkState = new TrunkState.Builder();
trunkState.setLockState(new Property(Lock.UNLOCKED));
trunkState.setPosition(new Property(Position.OPEN));
builder.addProperty(new Property(trunkState.build()));

ControlMode.Builder controlCommand = new ControlMode.Builder();
controlCommand.setMode(new Property(ControlModeValue.STARTED));
builder.addProperty(new Property(controlCommand.build()));

// build the actual vehicleStatus command
VehicleStatus status = builder.build();
// get the raw bytes of the vehicle status
byte[] command = status.getByteArray();

A signature and a nonce can be added to any of the command's builders:

VehicleStatus.Builder builder = getVehicleStatusBuilderWithoutSignature();
// set the nonce
builder.setNonce(new Bytes("324244433743483436"));
// get the temporary data that needs to be signed
Bytes bytesToBeSigned = builder.build().getSignedBytes();
// sign it
Bytes sig = Crypto.sign(bytesToBeSigned, privateKey);
// add the signature property
builder.setSignature(sig);
// get the final bytes with signature
Bytes command = builder.build();

Adding a new Capability

  • Add the Identifier in Identifier.java
  • Follow, for instance, Fueling.java to add the capability-s skeleton commands.
  • Create the tests. Copy this from previous FuelingTest.
  • Implement the new Capability commands.

OEM

Some commands are not available if using AutoAPI on the vehicle (OEM) side. For them to work, the environment needs to be set to VEHICLE in CommandResolver:

CommandResolver.setEnvironment(CommandResolver.Environment.VEHICLE);