Customize the Alexa Car Control Feature
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:
- Edit the
examples/alexa/app/src/main/res/values/alexa_ids.xml
file and add your own Alexa IDs. - Set the
disableAlexaDeviceIdBuildTimeCheck
Gradle property totrue
to disable the build-time check for Alexa IDs.
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 yourCustomCarControlHandlerService
module (for examplesrc/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 theaacs_customcarcontrol_config.json
file into theaacsConfiguration
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 null10 }1112override 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:
-
Add a
custom_assets.json
file to the Android assets of yourCustomCarControlHandlerService
module (for examplesrc/main/assets/config/custom_assets.json
). -
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. -
In the initialization of your
CustomCarControlHandlerService
, copy thecustom_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, so4 // that it can be found by AACS.5 copyCustomAssets()6 ...7 }89 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 } -
Add a reference to the
custom_assets.json
file in theaacs_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} -
In your Car Control configuration (
aacs_customcarcontrol_config.json
), you can then refer to your custom assets by theassetId
defined in thecustom_assets.json
file. For example, to define an endpoint that includes a custom asset in its list offriendlyNames
:
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 withPOWER
capability type) - toggle the state of an endpoint property (
SetControllerValue
messages withTOGGLE
capability type) - set the mode of an endpoint property (
SetControllerValue
messages withMODE
capability type) - set the numeric setting of an endpoint property (
SetControllerValue
message withRANGE
capability type) - adjust (increase or decrease) the mode of an endpoint property (
AdjustControllerValue
message withMODE
capability type) - adjust (increase or decrease) the numeric setting of an endpoint property (
AdjustControllerValue
message withRANGE
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.