Customize the Alexa Car Control Feature

Last edit: 2023.08.09

Additional requirements exist for using Amazon Alexa in your TomTom Digital Cockpit product.

One of the Alexa Auto features that will most likely need customizations for your own vehicle requirements is Car Control. The Car Control module enables an OEM to build a custom experience that allows users to use Alexa to voice-control vehicle features.

A full description of the Car Control module and its features is available in the Alexa Auto documentation.

TomTom Digital Cockpit offers a stock implementation of a CarControl handler service, aimed at controlling heating, ventilation, and air-conditioning (HVAC) of the vehicle by interacting with the VehicleHvacService.

To allow an OEM to customize the stock Car Control service implementation (or completely replace it), the TomTom Digital Cockpit platform offers the possibility of implementing an Alexa handler service for the CarControl topic. For more information on how to create a custom Alexa handler service, see the Create a Custom Alexa Handler Service tutorial.

Example app

The TomTom Digital Cockpit SDK comes with an example Alexa app. See directory examples/alexa. The app includes an example CustomCarControlHandlerService, showing:

  • How to define custom CarControl endpoints and assets.
  • How to handle user requests such as "Turn on the light", "Increase the light brightness" or "Switch on my custom device".

To build the Alexa example app, you should edit the top-level gradle.properties file:

optInToAlexaExamples=true

Alternatively, you can set this Gradle property from the command-line:

./gradlew assemble -PoptInToAlexaExamples=true

Additionally, you will need to register your own Alexa product with Amazon and obtain a set of Alexa IDs, as explained on the Register your Alexa product with Amazon page.

Once you have your own set of Alexa IDs, you can configure the Alexa example app:

Alternatively, you can also configure the Alexa example app by setting the alexaDeviceInfoClientId and alexaDeviceInfoProductId properties in the top-level local.properties file or as Gradle properties. In this case you won't need to set disableAlexaDeviceIdBuildTimeCheck to true.

How to create a custom Car Control handler service

The following sections describe how to create a custom Car Control handler service.

Create a minimal Custom Car Control handler service module

Follow the steps in Create a service implementation module to create the initial CustomCarControl handler service module and in Implement the Alexa Handler service to implement a minimal CustomCarControlHandlerService implementation.

Define a custom Car Control configuration

The Car Control configuration informs the Alexa Auto Engine which vehicle features to advertise to Alexa for control by the user. More details can be found on the Configuring the Car Control Module page.

The stock TomTom Digital Cockpit Alexa Car Control service dynamically generates a Car Control configuration for a number of endpoints, based on information retrieved from the VehicleHvacService:

  • Air Conditioning
  • Climate Control
  • Fan
  • Vent
  • Heater
  • Seat Heater

It's possible to extend this stock Car Control configuration with additional endpoints, to handle voice control of other vehicle features. The custom Car Control configuration will be merged with the stock Car Control configuration by the TomTom Digital Cockpit platform.

To define a custom Car Control configuration:

  • Add an aacs_customcarcontrol_config.json file to the Android assets of your CustomCarControlHandlerService module (for example src/main/assets/config/aacs_customcarcontrol_config.json).

  • Define your custom Car Control configuration in the aacs_customcarcontrol_config.json file. The format of the file is described in the Alexa Auto Configuration Format page.

  • In the initialization of your CustomCarControlHandlerService, read the contents of the aacs_customcarcontrol_config.json file into the aacsConfiguration property.
    src/main/kotlin/com/example/ivi/example/alexa/customcarcontrolhandler/CustomCarControlHandlerService.kt

    1private fun readAacsConfig(context: Context): String? =
    2 try {
    3 with(context) {
    4 val filePath = "config/aacs_customcarcontrol_config.json"
    5 assets.open(filePath).bufferedReader().use { it.readText() }
    6 }
    7 } catch (exception: IOException) {
    8 tracer.e("AACS configuration file not found.", exception)
    9 null
    10 }
    11
    12override fun onCreate() {
    13 ...
    14 aacsConfiguration = readAacsConfig(context)
    15 ...
    16}

Define custom Car Control assets

As explained in the Alexa Auto documentation, assets, identified by unique IDs, group a voice-accessible friendly name like "air conditioner" into a named group of synonyms and translations for all supported languages.

The Alexa Auto SDK provides a default automotive catalog of assets which can be used when building the Car Control configuration, but it also allows clients to define custom assets if they are not already part of the default catalog. This is explained in the Additional Notes about Assets.

To define and use custom assets:

  1. Add a custom_assets.json file to the Android assets of your CustomCarControlHandlerService module (for example src/main/assets/config/custom_assets.json).

  2. Add your custom assets definitions to the custom_assets.json file. The format of this file must follow the same schema as the automotive catalog of assets.

  3. In the initialization of your CustomCarControlHandlerService, copy the custom_assets.json file to the app's internal storage:
    src/main/kotlin/com/example/ivi/example/alexa/customcarcontrolhandler/CustomCarControlHandlerService.kt

    1 override fun onCreate() {
    2 ...
    3 // Copy the `custom_assets.json` file from the assets storage to the internal storage, so
    4 // that it can be found by AACS.
    5 copyCustomAssets()
    6 ...
    7 }
    8
    9 private fun copyCustomAssets() {
    10 try {
    11 with(context) {
    12 val customAssetsPath = "config/custom_assets.json"
    13 assets.open(customAssetsPath).use { inputFile ->
    14 FileOutputStream(filesDir?.resolve("custom_assets.json")).use {
    15 inputFile.copyTo(it)
    16 }
    17 }
    18 }
    19 } catch (exception: IOException) {
    20 tracer.e("Failed to copy custom assets file.", exception)
    21 }
    22 }
  4. Add a reference to the custom_assets.json file in the aacs_customcarcontrol_config.json file.
    src/main/assets/config/aacs_customcarcontrol_config.json

    1{
    2 "aacs.localVoiceControl": {
    3 "CarControl": {
    4 "CustomAssetsFilePath": "/data/user/10/com.example.ivi.example.alexa.app/files/custom_assets.json"
    5 }
    6 },
    7 "aacs.carControl": {
    8 "assets": {
    9 "customAssetsPath": "/data/user/10/com.example.ivi.example.alexa.app/files/custom_assets.json"
    10 },
    11 ...
    12 }
    13}
  5. In your Car Control configuration (aacs_customcarcontrol_config.json), you can then refer to your custom assets by the assetId defined in the custom_assets.json file. For example, to define an endpoint that includes a custom asset in its list of friendlyNames:
    src/main/assets/config/aacs_customcarcontrol_config.json

    1{
    2 "endpointId": "default.custom_device",
    3 "endpointResources": {
    4 "friendlyNames": [
    5 {
    6 "@type": "asset",
    7 "value": {
    8 "assetId": "My.Alexa.Automotive.DeviceName.CustomDevice"
    9 }
    10 }
    11 ]
    12 }
    13}

Handle Car Control messages

Once you have configured your CustomCarControlHandlerService, you can implement parsing and handling of the CarControl AASB JSON messages, as explained in Parsing AASB messages.

You will need to perform different actions on your vehicle devices, depending on the type of message you receive:

  • change the power state of an endpoint (SetControllerValue messages with POWER capability type)
  • toggle the state of an endpoint property (SetControllerValue messages with TOGGLE capability type)
  • set the mode of an endpoint property (SetControllerValue messages with MODE capability type)
  • set the numeric setting of an endpoint property (SetControllerValue message with RANGE capability type)
  • adjust (increase or decrease) the mode of an endpoint property (AdjustControllerValue message with MODE capability type)
  • adjust (increase or decrease) the numeric setting of an endpoint property (AdjustControllerValue message with RANGE capability type)

Please refer to the Alexa Auto Using the Car Control Module AASB Messages page and to the example CustomCarControlHandlerService for more details on how to parse and handle these different types of messages.

Deploy your custom Car Control handler service

Follow the steps in Create a service host and Configure the service host deployment to deploy the custom Car Control handler service in your application.

References