Support Device Interactions with the ACK Device SDK

This page provides an overview of how to support ACK device interactions in your host microcontroller unit (HMCU) application logic by using the Alexa Connect Kit (ACK) Device SDK.

Support device states

As you transition through the module lifecycle, your device takes on various device states. These states dictate what your device can and can't do at a given moment in time. The ACK Device SDK uses the ACKUser_OnLifecycleStateChange callback in your application to indicate the transition between the states.

For more details about designing your device to handle the following ACK_LifecycleState variables, see Device States.

Device state SDK variable Description

ACK_LIFECYCLE_UNAVAILABLE

ACK module isn't available.

ACK_LIFECYCLE_BOOTED

ACK module is booted.

ACK_LIFECYCLE_FACTORY_RESET_IN_PROGRESS

ACK module is processing a factory reset.

ACK_LIFECYCLE_NOT_REGISTERED

ACK device isn't registered to Alexa and isn't available for device setup.

ACK_LIFECYCLE_IN_SETUP_MODE

ACK device isn't registered to Alexa and is available for device setup.

ACK_LIFECYCLE_CONNECTED_TO_ALEXA

ACK device is registered with Alexa and established a connection to the Alexa services.

ACK_LIFECYCLE_NOT_CONNECTED_TO_ALEXA

ACK device is registered with Alexa but hasn't established a connection to the Alexa services.

The following example shows a sample implementation of the ACKUser_OnLifecycleStateChange callback that prints out the current state of a device.

void ACKUser_OnLifecycleStateChange(void)
{
    bool anyActive = false;

    // Setup is handled specially because it has substates.
    if (ACK_LIFECYCLE_IN_SETUP_MODE == ACK_LifecycleState)
    {
        ACK_DEBUG_PRINT_I("ACK lifecycle state: SETUP MODE");

        // Display setup type messages.
        // If you have a simple display like a blinking LED, you should present the mode by priority
        // in the order shown here.
        if (ACK_LifecycleSubStateInfo.InSetupMode.IsUserGuidedSetupActive)
        {
            ACK_DEBUG_PRINT_I("   USER GUIDED SETUP");
            anyActive = true;
        }

        if (ACK_LifecycleSubStateInfo.InSetupMode.IsBarcodeScanSetupActive)
        {
            ACK_DEBUG_PRINT_I("   BARCODE SCAN");
            anyActive = true;
        }

        if (ACK_LifecycleSubStateInfo.InSetupMode.IsZeroTouchSetupActive)
        {
            ACK_DEBUG_PRINT_I("   ZERO TOUCH SETUP");
            anyActive = true;
        }

        if (!anyActive)
        {
            ACK_DEBUG_PRINT_I("   NO SETUP MODES ACTIVE");
        }

        switch (ACK_LifecycleSubStateInfo.InSetupMode.SetupStage)
        {
        case acp_setup_stages_discoverable:
            ACK_DEBUG_PRINT_I("ACK FFS Stage: DISCOVERABLE");
            break;
        case acp_setup_stages_setup_in_progress:
            ACK_DEBUG_PRINT_I("ACK FFS Stage: SETUP IN PROGRESS");
            break;
        case acp_setup_stages_registered:
            ACK_DEBUG_PRINT_I("ACK FFS Stage: REGISTERED");
            break;
        default:
            ACK_DEBUG_PRINT_I("ACK FFS Stage: UNKNOWN");
            break;
        }

        return;
    }

    // Update user-facing elements based on the lifecycle state (other than setup, which was handled above).
    switch (ACK_LifecycleState)
    {
    case ACK_LIFECYCLE_UNAVAILABLE:
        ACK_DEBUG_PRINT_I("ACK lifecycle state: UNAVAILABLE");
        break;

    case ACK_LIFECYCLE_BOOTED:
        ACK_DEBUG_PRINT_I("ACK lifecycle state: BOOTED");
        break;

    case ACK_LIFECYCLE_FACTORY_RESET_IN_PROGRESS:
        ACK_DEBUG_PRINT_I("ACK lifecycle state: FACTORY RESET IN PROGRESS");
        break;

    case ACK_LIFECYCLE_NOT_REGISTERED:
        ACK_DEBUG_PRINT_I("ACK lifecycle state: NOT REGISTERED");
        break;

    case ACK_LIFECYCLE_NOT_CONNECTED_TO_ALEXA:
        ACK_DEBUG_PRINT_I("ACK lifecycle state: NOT CONNECTED TO ALEXA");
        break;

    case ACK_LIFECYCLE_CONNECTED_TO_ALEXA:
        ACK_DEBUG_PRINT_I("ACK lifecycle state: CONNECTED TO ALEXA");
        break;

    default:
        ACK_DEBUG_PRINT_I("ACK lifecycle state: UNKNOWN");
        break;
    }
}

Support user-initiated triggers

A user-initiated trigger is an action that occurs on your ACK-based device, after a user completes a pre-programmed pattern, such as pressing a unique button combination. You typically use these triggers to transition devices into a specific device state.

For more details about designing your device to handle these triggers, see User-Initiated Triggers.

User-initiated trigger SDK variable Description Action

ACKUser_DoesUserWantFactoryReset

Initiate a factory reset.

Application must return true to start the factory reset.

ACKUser_DoesUserWantUserGuidedSetup

Initiate User-Guided Setup (UGS) mode.

Application must return true to start UGS.

ACKUser_DoesUserWantToSubmitLogs

Initiate log upload.

Application must return true to start uploading the logs.

ACKUser_EraseUserSettings

Erase user settings stored on the device (not a factory reset).

Application must to erase on-device user preferences (if any) and return to the factory defaults.

ACKUser_IsDeviceInUse

Checks if the device is currently operating. For example, when a microwave is cooking. Use this mode to prevent potentially disruptive operations, such as sending an over-the-air (OTA) update.

Application should return true when the device is in-use.

ACKUser_GetFirmwareVersion

Retrieve firmware version of a device.

Application must to return the current device firmware version as a 64-bit integer. Report the device firmware versions in ascending order.

The ACK Device SDK defines several application callbacks that should be used to change the state of the ACK module in response to the user interactions. The following code example shows how you could program your user-initiated triggers to respond to device states.

// The manner in which a user initiates factory reset is highly device-specific. For your product to
// support factory reset, user-guided setup, or submitting device logs, these callbacks need to return true when certain user input is detected

bool ACKUser_DoesUserWantFactoryReset(void)
{
    // if hardware detected factory reset combination
    if(g_factory_reset_detected) {
        g_factory_reset_detected = false;
        return true;
    }
    return false;
}

bool ACKUser_DoesUserWantUserGuidedSetup(void)
{
    // if hardware detected user guided setup combination
    if(g_ugs_detected) {
        g_ugs_detected = false;
        return true;
    }
    return false;
}

bool ACKUser_DoesUserWantToSubmitLogs(void)
{
    // if hardware detected log submit combination
    if(g_log_submit_detected) {
        g_log_submit_detected = false;
        return true;
    }
    return false;
}