ACK Development Overview

Meet the following prerequisites before you begin development of a Alexa Connect Kit (ACK)-based device.

  • Purchase the ACK hardware listed in Phase 2: Product design.
  • Create an Amazon developer account and access the ACK developer portal.
  • Download the ACK Device SDK. In general, all new devices should use the latest combination of the ACK module firmware, ACK Device SDK, and related tools. Some Smart Home APIs are only available with the ACK Device SDK 4 and higher.
  • Download and set up the ACK Module Utility.

High level development steps

The following steps walk you through the general development process to build an ACK-based device:

  1. Create a blueprint of your product by using the ACK developer console, otherwise known as a virtual product. In this step, you define the overall experience of your device, such as the type of device, it's smart home capabilities, and how users can interact with your device using Alexa. To get started, you can use device templates to decide which Smart Home APIs to select for your device.

    For example: If you build a fan, you might include the PowerController capability interface to control it's on and off status. At this point, your ACK module still doesn't understand it's a product, such as a fan, a coffee machine, or a light switch. This is because you haven't associated your virtual product to your ACK hardware.

  2. Associate your virtual product with an ACK module on the device by using the ACK Module Utility. This process is called product provisioning. Provisioning allows Alexa to control your device using the capability interfaces that you defined in your virtual product.

    For example: When you provision your ACK module, it becomes associated with the virtual product you created, such as a fan.

  3. Build your host microcontroller unit (HMCU) application logic for your device using the ACK Device SDK. This process allows your device to receive and respond to Alexa commands, implement connected device lifecycle, and use other ACK features. Other features might include receiving over-the-air (OTA) updates or reporting device metrics.

    For example: When a user makes a request to your product through Alexa, your HMCU application uses the ACK Device SDK to process the request and acts correspondingly, such as turning on the fan motor.

High-level interaction between Alexa and ACK

The following diagrams illustrate the high-level interaction between Alexa services and the ACK module.

Components of an ACK-based smart device
Components of an ACK-based smart device

Diagram one shows a fan turning on after a voice request from a user. There are two important development concepts to understand here:

  • First, the Alexa service sends a Alexa.PowerController TurnOn directive to the ACK services. Your ACK-based device can process this directive because you defined this capability in your virtual product. If you don't define this capability in your virtual product, it won't work.
  • Second, the ACK module interprets the Alexa.PowerController TurnOn directive and communicates this directive to your HMCU. After this occurs, the ACK Device SDK invokes the ACKUser_OnPowerControllerDirective callback method in your HMCU application to handle the incoming PowerController's directives. The ACK Device SDK communicates to your HMCU app, which contains your implementation of the ACKUser_OnPowerControllerDirective. This controls the power-on logic for your fan that you programmed, such as turning the fan on and changing to the last used speed setting.

Diagram two provides more specific details about what happens when the ACK module interprets the PowerController directive.

  • The ACKUser_OnPowerControllerDirective callback processes the directive. If the processing is successful, the callback uses the ACK_CompleteDirectiveWithSuccess API. If there an error, the callback uses one of the ACK_CompleteDirectiveWithXXXError APIs instead.
  • To build a response to the Alexa directive, the ACK Device SDK invokes the power property callback method, which uses the ACK_AddPowerControllerProperty API to provide the state of the power property.
  • After calling these methods, the SDK passes the directive's response to the ACK module. The ACK module then communicates the response to the Alexa services.

Supported smart home capability interfaces

Each supported smart home capability interface has an equivalent ACK Device SDK callback routine that processes the capability's directives.

For more details about using the callbacks, see the ACK Device SDK documentation bundled with the SDK download.

Smart home capability interface (Alexa.*) ACK Device SDK callback

BrightnessController

ACKUser_OnBrightnessControllerDirective

ColorController

ACKUser_OnColorControllerDirective

ColorTemperatureController

ACKUser_OnColorTemperatureControllerIncreaseTemperatureDirective
ACKUser_OnColorTemperatureControllerDecreaseTemperatureDirective
ACKUser_OnColorTemperatureControllerSetTemperatureDirective

Cooking and Cooking.ErrorResponse

ACKUser_OnCookingSetModeDirective

Cooking.FoodTemperatureController

ACKUser_OnCookingFoodTemperatureControllerCookByFoodTemperatureDirective

Cooking.FoodTemperatureSensor and Cooking.PresetController

ACKUser_OnCookingPresetControllerCookByPresetDirective

Cooking.TemperatureController

ACKUser_OnCookingTemperatureControllerCookByTemperatureDirective
ACKUser_OnCookingTemperatureControllerAdjustCookingTemperatureDirective

Cooking.TemperatureSensor

-

Cooking.TimeController

ACKUser_OnCookingTimeControllerCookByTimeDirective
ACKUser_OnCookingTimeControllerAdjustCookTimeDirective

ModeController

ACKUser_OnModeControllerDirective

PercentageController

ACKUser_PercentageControllerDirective

PowerController

ACKUser_OnPowerControllerDirective

RangeController

ACKUser_OnRangeControllerDirective

ThermostatController

ACKUser_OnThermostatControllerSetTargetTemperatureDirective
ACKUser_OnThermostatControllerAdjustTargetTemperatureDirective
ACKUser_OnThermostatControllerSetThermostatModeDirective
ACKUser_OnThermostatControllerResumeScheduleDirective

TimeHoldController

ACKUser_OnTimeHoldControllerHoldDirective
ACKUser_OnTimeHoldControllerResumeDirective

ToggleController

ACKUser_OnToggleControllerDirective

Example: high-level development steps to build a fan

The following example walks you through the high-level development steps to build a fan, as described in the previous sections.

To build a fan

  1. In the developer console, create a virtual product for your fan.
  2. In the developer console JSON editor, add the Alexa.PowerController capability interface to enable the power on and off feature.

    The following example shows the PowerController JSON that you add in the JSON editor.

    "capabilities": {
      "type": "AlexaInterface",
      "interface": "Alexa.PowerController",
      "version": "3",
      "properties": {
      "supported": [
        {
          "name": "powerState”
        }
      ],
      "proactivelyReported": true,
      "retrievable": true
      }
     }
    
  3. Provision your module as a product by moving to the product provisioned state.

    The following example shows the ACK module utility command to provision your module as a product.

    $ java -jar <path>/ackmoduleutility.jar provision -p <port> --provisionconfigfile <path>/ProvisioningInfo_[devicetypeid].conf
    
  4. Register your device with Alexa using the Alexa app.

    Alexa now understands that your product is a fan with that uses the Alexa.PowerController capability interface. However, you haven't uploaded any application code to your HMCU, so Alexa can't control your device yet.

  5. Develop your application logic by using the ACK Device SDK.

    The following example defines the fan's power state property and its callback in the application.

    #include "ack_power_controller.h"
    
    ...
    
    // Adds the power state property to an outgoing event.
    static bool AddPowerStateProperty(uint32_t propertyOrdinal, unsigned propertyFlags);
    
    // Property ordinals. Used to map from a property or a set of properties to a routine in our code
    // that adds the property or properties to an outgoing event (directive response, state report, or
    // change report).
    // The actual values here can be anything in the range [0-31].
    // For this sample, there's only one property, for the power state.
    #define POWER_STATE_PROPERTY 1
    
    // Required table that maps properties to routines in our code that populate an outgoing event such as
    // a directive response, state report, or change report.
    ACKPropertyTableEntry_t ACKUser_PropertyTable[] =
    {
        { POWER_STATE_PROPERTY, AddPowerStateProperty },
    
        // An entry with a NULL callback function terminates the table.
        { 0, NULL }
    };
    
    ...
    
    // ACK_Process calls this to add properties when it's constructing an outgoing event such as a directive
    // response, state report, or change report. The property ordinal is unused because the Power Controller
    // capability is single-instance; there can be a maximum of one of them on any device.
    static bool AddPowerStateProperty(uint32_t propertyOrdinal, unsigned propertyFlags)
    {
        ACKStateCommon_t propertyState = { 0, 0, propertyFlags };
        ACKError_t error;
    
        error = ACK_AddPowerControllerProperty(&propertyState, Hardware_IsPowerOn());
        if (ACK_NO_ERROR != error)
        {
            ACK_DEBUG_PRINT_E("Error %u adding power state property.", error);
            return false;
        }
    
        return true;
    }
    

    You also implement an ACKUser_OnPowerControllerDirective callback to process incoming PowerController directives.

    // Handler callback for incoming Alexa.PowerController directives.
    // ACK_Process dispatches to this routine if such an incoming event is available from the
    // ACK connectivity module when ACK_Process is called.
    
    void ACKUser_OnPowerControllerDirective(int32_t correlationId, bool powerOn)
    {
        bool powerStateChanged;
    
        ACK_DEBUG_PRINT_I("Received power controller directive; power %u.", powerOn);
    
        // Track whether the power state is actually changing. If so, we want to indicate this when completing
        // the directive, so an Alexa change report will be sent automatically.
        powerStateChanged = (0 == Hardware_IsPowerOn()) != (0 == powerOn);
    
        // control the device power
        Hardware_SetPowerState(powerOn);
    
        // complete the PowerController directive and indicate changed properties
        ACK_CompleteDirectiveWithSuccess(
            correlationId,
            ACK_PROPERTY_BIT(POWER_STATE_PROPERTY),
            powerStateChanged ? ACK_PROPERTY_BIT(POWER_STATE_PROPERTY) : 0);
    }
    
  6. Upload your application code to your device.

    You can now register your device with Alexa and test out functionality.