Automations are a way to automate tasks and device settings in a home.
Automations have been available in the Google Home ecosystem as Routines in the
Google Home app (GHA) and through the automation script editor on
Google Home for web.

Now, Automations in the Google Home ecosystem are available through the Home
APIs for Android. They use the same basic concepts used in
GHA Routines and the script editor, but with
enhanced features and capabilities only possible through the Home APIs,
including:

- Access to all Matter standard and smart home traits for a device, as presented in the Home APIs.
- Support for sequential, parallel, and select execution flows.

Automations are written using Automation DSL, a domain-specific language
designed for building automations in Kotlin.

> [!NOTE]
> **Note:** Automation API supports most traits in the Home APIs, but support may be limited to specific attributes, events, and commands for a given trait. See [Automation API trait support on Android](https://developers.home.google.com/apis/android/automation/supported-traits.md.txt) for more details.

Any traits and types that you intend to use in your app with the Device \&
Structure or Automation APIs must be registered at initialization. See
[Initialize the home on Android](https://developers.home.google.com/apis/android/initialize.md.txt).

## Guidance if user revokes full permissions

If the user revokes full permissions, all existing automations will
stop working. Also, if the user revokes access to specific devices, then
starters, conditions, and actions associated with those devices will
stop working.

**Each time the app starts, be sure to check that the permissions
are still in effect. If they have been revoked, then be sure that all previous
data are removed, including any data cached in the application.**

When structure access is revoked, a
[`StructureAccessRevokedEvent`](https://developers.home.google.com/partners/services/camera/cloud-events#structure_grants)
is delivered to your cloud backend. Refer to
[Structure grants](https://developers.home.google.com/partners/services/camera/cloud-events#structure_grants) for
the end-to-end partner cloud and mobile app revocation workflow.

## Developer journey

The Automation API is one portion of a larger development journey. It comes
after integrating the Structure and Device APIs to ensure that when a user wants
to use an automation, they can do so.

1. The developer plans their automation, and defines it using the Automation DSL.
2. The developer embeds the automation definition in a Kotlin Android app.
3. The app presents automations to a user based on information about their devices, including traits, attributes, commands, and events, gathered using the Discovery API or Device API.
   1. With the Discovery API, the app can generate a draft automation customized to the device types and traits present in the user's structure, with or without the user's input.
   2. The Device API can provide most of the same information as the Discovery API, but it's not optimized for automation use cases. See [Compare the Device API and Discovery API](https://developers.home.google.com/apis/automation/discovery#compare_the_device_api_and_discovery_api) for more details.
4. The app creates the actual automation that is keyed to the selected structure.
5. The automation is now available in the user's structure and can be executed or deleted using Structure API methods.

The user may create new instances of the automation at any time, selecting a
different structure or, depending on the app logic, perhaps a different set of
devices. Each time they do so, the app generates a new instance of the
automation.

In the most basic scenario, you might suggest to your users a predefined
automation that performs a relatively basic task. Alternatively, you could
present a skeleton of an automation that the user customizes to meet their
needs. Or you could write an open-ended automation editor that allows the user
to construct complex automations using all the building blocks available in the
Automation API.

### Create and manage automations

To create and manage automations on Android:

1. Register all device types and traits referenced by your automations in the [`FactoryRegistry`](https://developers.home.google.com/reference/kotlin/com/google/home/FactoryRegistry.md.txt) passed to [`HomeConfig`](https://developers.home.google.com/reference/kotlin/com/google/home/HomeConfig.md.txt) during SDK initialization. For registration details, see [Initialize the
   home on Android](https://developers.home.google.com/apis/android/initialize).
2. Build your `DraftAutomation` ([`BaseAutomation`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/BaseAutomation.md.txt)) using the [`automation()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/package-summary.md.txt#automation(kotlin.Function1)) DSL and call standard [`HasAutomations`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasAutomations.md.txt) methods on the [`Structure`](https://developers.home.google.com/reference/kotlin/com/google/home/Structure.md.txt) object:
   - Call [`createAutomation()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasAutomations.md.txt#createAutomation(com.google.home.automation.BaseAutomation)) to create an automation in the structure.
   - Call [`automations()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasAutomations.md.txt#automations()) to list or retrieve automations created by your app in the structure.
   - Call [`update()`](https://developers.home.google.com/reference/kotlin/com/google/home/Updatable.md.txt#update(kotlin.Function1,kotlin.Function1)) on an [`Automation`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/Automation.md.txt) instance to update its metadata or replace its `automationGraph`.
   - Call [`deleteAutomation()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasAutomations.md.txt#deleteAutomation(com.google.home.Id)) to remove an automation by ID.

```kotlin
val draft = automation {
  name = "Turn on light"
  description = "Turn on light2 when light1 turns on."
  sequential {
    val starterNode = starter<_>(light1, OnOffLightDevice, OnOff)
    condition { expression = starterNode.onOff equals true }
    action(light2, OnOffLightDevice) { command(OnOff.on()) }
  }
}

val createdAutomation = structure.createAutomation(draft)
```

For complete DSL syntax and CRUD code examples, see [Build an automation on
Android](https://developers.home.google.com/apis/android/automation/build).

## Automation suggestions

[Implemented in Sample App for Android](https://developers.home.google.com/apis/android/sample-app/build.md.txt)

The Home APIs can suggest automations for a
[`Structure`](https://developers.home.google.com/reference/kotlin/com/google/home/Structure.md.txt) based on factors
such as the device types present in the space.

Automation suggestions are represented by the
[`AutomationSuggestion`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/AutomationSuggestion.md.txt)
class.

The [`Structure`](https://developers.home.google.com/reference/kotlin/com/google/home/Structure.md.txt) interface
encompasses the
[`HasSuggestions`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasSuggestions.md.txt)
interface, which provides the
[`suggestions()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasSuggestions.md.txt#suggestions())
function, which returns a collection of automation suggestions.

The
[`likeSuggestion()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasSuggestions.md.txt#likeSuggestion(kotlin.String))
and
[`dislikeSuggestion()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasSuggestions.md.txt#dislikeSuggestion(kotlin.String))
methods are intended to be wired to
and
UI controls that the user can tap
to provide feedback.

A third method,
[`clearSuggestionFeedback()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasSuggestions.md.txt#clearSuggestionFeedback(kotlin.String)),
lets the user remove their feedback for a suggested automation.

User feedback influences future suggestions.

This example demonstrates how to retrieve the available automation suggestions
for a [`Structure`](https://developers.home.google.com/reference/kotlin/com/google/home/Structure.md.txt), extract a
suggestion ID, and record user feedback using
[`likeSuggestion()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasSuggestions.md.txt#likeSuggestion(kotlin.String)),
[`clearSuggestionFeedback()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasSuggestions.md.txt#clearSuggestionFeedback(kotlin.String)),
and
[`dislikeSuggestion()`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/HasSuggestions.md.txt#dislikeSuggestion(kotlin.String)).

```kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.home.Structure
import kotlinx.coroutines.launch

class AutomationSuggestionsViewModel(private val structure: Structure) : ViewModel() {

  fun loadAndGiveFeedback() {
    viewModelScope.launch {
      // 1. Fetch suggestions from structure
      val suggestions = structure.suggestions()
      val firstSuggestion = suggestions.firstOrNull() ?: return@launch

      // Extract string suggestion ID
      val suggestionId: String = firstSuggestion.id.id

      // 2. Like the suggestion (thumbs up)
      val liked = structure.likeSuggestion(suggestionId)

      // 3. Clear previous feedback if the user toggled it off
      if (liked) {
        structure.clearSuggestionFeedback(suggestionId)
      }

      // 4. Dislike the suggestion (thumbs down)
      structure.dislikeSuggestion(suggestionId)
    }
  }
}
```

## Dynamic command parameters

Dynamic command parameters allow developers to construct action parameters that
resolve dynamically at runtime rather than relying strictly on static, constant
values. This enables two primary capabilities:

- References that pass the value of a property from a starter (such as an event payload) or state reader node, or from local variables declared within the automation flow.
- Expressions that capture runtime dynamic values (such as an event property or state value) and pass the dynamic value directly into a command parameter.

### Use case

Bind a physical rotary switch that sends a multi-press event to a dimmable
light. The count of clicks is the dynamic value passed into a `LevelControl`
step command at runtime.

### How dynamic parameters work

In the Automation DSL on Android, command parameters accept
[`Expression`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/Expression.md.txt) or
[`Reference`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/Reference.md.txt) instances
directly in place of static constant values. The DSL encapsulates these into
[`Parameter`](https://developers.home.google.com/reference/kotlin/com/google/home/automation/Parameter.md.txt)
definitions when constructing the automation.


### Validation rules

Dynamic command parameters follow these validation constraints:

- Dynamic parameters are assumed to be structurally valid during discovery because discovery APIs only evaluate concrete value constraints for static arguments.
- Reference or expression nodes must appear upstream in the automation graph before they are referenced in a downstream command action.

### Use dynamic command parameters on Android

Pass dynamic expressions directly to command parameters:

```kotlin
import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch

val keypressAutomation = automation {
  name = "Dynamic command parameters example"
  description = "Pass starter event field directly to command"
  sequential {
    val dimmerStarter = starter(
      dimmerSwitch,
      DimmerSwitchDevice,
      Switch.MultiPressOngoingEvent,
    )

    val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
      dimmerStarter,
      Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
    )

    action(dimmableLight, DimmableLightDevice) {
      command(
        LevelControl.step(
          stepMode = StepModeEnum.Up,
          stepSize = clickCountExpr,
        )
      )
    }
  }
}
```

Alternatively, assign an expression to a local variable declaration and
reference the variable later in the flow:

```kotlin
import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.automation.variable
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch

val myAutomationWithVariable = automation {
  name = "Dynamic command parameters with variables"
  description = "Declare a variable, assign value, and pass reference"
  sequential {
    val dimmerStarter = starter(
      dimmerSwitch,
      DimmerSwitchDevice,
      Switch.MultiPressOngoingEvent,
    )

    val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
      dimmerStarter,
      Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
    )

    val clickCountVar = variable<UInt>()
    clickCountVar.assign(clickCountExpr)

    action(dimmableLight, DimmableLightDevice) {
      command(
        LevelControl.step(
          stepMode = StepModeEnum.Up,
          stepSize = clickCountVar,
        )
      )
    }
  }
}
```

### Type constraints

Ensure that the types of variables and expressions align with the receiving
command parameter's required Matter schema type
definition (such as `UShort`, `UByte`, or `UInt8`).

## Resource limits

The following limits apply to automations in the Home APIs:

| Metric | Limit |
|---|:---:|
| Maximum number of automations per structure | 64 |
| Maximum number of nodes per automation | 128 |
| Maximum number of expression nodes per automation | 64 |
| Maximum number of automation instances per structure | 1024 |
| Maximum number of automation instances per developer per structure | 64 |
| Maximum number of executions per structure per day | 1024 |
| Maximum number of executions per developer per structure per day | 128 |
[*Table: Automation API resource limits*]

> [!NOTE]
> **Note:** These limits are the current defaults, and are subject to change by Google.