Visão geral da API Automation no Android

As automações são uma maneira de automatizar tarefas e configurações de dispositivos em uma casa. As automações estão disponíveis no ecossistema do Google Home como Rotinas no Google Home app (GHA) e pelo automation script editor no Google Home for web.

Agora, as automações no ecossistema do Google Home estão disponíveis nas APIs Home para Android. Elas usam os mesmos conceitos básicos das Rotinas do GHA e do script editor, mas com recursos e capacidades aprimorados que só são possíveis com as APIs Home, incluindo:

  • Acesso a todas as características padrão do Matter e do smart home para um dispositivo, conforme apresentado nas APIs Home.
  • Suporte para fluxos de execução sequenciais, paralelos e de seleção.

As automações são escritas usando a DSL de automação, uma linguagem específica de domínio projetada para criar automações em Kotlin.

Todos os atributos e tipos que você pretende usar no app com as APIs Device & Structure ou Automation precisam ser registrados na inicialização. Consulte Inicializar a casa no Android.

Orientação se o usuário revogar as permissões completas

Se o usuário revogar as permissões completas, todas as automações atuais vão parar de funcionar. Além disso, se o usuário revogar o acesso a dispositivos específicos, as ativações, condições e ações associadas a eles vão parar de funcionar.

Sempre que o app for iniciado, verifique se as permissões ainda estão em vigor. Se elas tiverem sido revogadas, verifique se todos os dados anteriores foram removidos, incluindo os dados armazenados em cache no aplicativo.

Quando o acesso à estrutura é revogado, um StructureAccessRevokedEvent é enviado ao back-end na nuvem. Consulte Estruturar concessões para o fluxo de trabalho de revogação de ponta a ponta do app para dispositivos móveis e da nuvem do parceiro.

Jornada do desenvolvedor

A API Automation é uma parte de uma jornada de desenvolvimento maior. Ela vem depois da integração das APIs Structure e Device para garantir que, quando um usuário quiser usar uma automação, ele possa fazer isso.

  1. O desenvolvedor planeja a automação e a define usando a DSL de automação.
  2. O desenvolvedor incorpora a definição de automação em um app Android em Kotlin.
  3. O app apresenta automações para um usuário com base em informações sobre os dispositivos dele, incluindo atributos, comandos e eventos, coletados usando a API Discovery ou a API Device.
    1. Com a API Discovery, o app pode gerar um rascunho de automação personalizado para os tipos de dispositivo e atributos presentes na estrutura do usuário, com ou sem a entrada do usuário.
    2. A API Device pode fornecer a maioria das mesmas informações que a API Discovery, mas não é otimizada para casos de uso de automação. Consulte Comparar a API Device e a API Discovery para mais detalhes.
  4. O app cria a automação real que é vinculada à estrutura selecionada.
  5. A automação agora está disponível na estrutura do usuário e pode ser executada ou excluída usando os métodos da API Structure.

O usuário pode criar novas instâncias da automação a qualquer momento, selecionando uma estrutura diferente ou, dependendo da lógica do app, talvez um conjunto diferente de dispositivos. Sempre que isso acontece, o app gera uma nova instância da automação.

No cenário mais básico, você pode sugerir aos usuários uma automação predefinida que realiza uma tarefa relativamente básica. Como alternativa, você pode apresentar um esqueleto de uma automação que o usuário personaliza para atender às necessidades dele. Ou você pode criar um editor de automação aberto que permita ao usuário criar automações complexas usando todos os elementos básicos disponíveis na API Automation.

Criar e gerenciar automações

Para criar e gerenciar automações no Android:

  1. Registre todos os tipos de dispositivo e atributos referenciados pelas automações no FactoryRegistry transmitido para HomeConfig durante a inicialização do SDK. Para detalhes sobre o registro, consulte Inicializar a casa no Android.
  2. Crie seu DraftAutomation (BaseAutomation) usando a DSL automation() e chame métodos HasAutomations padrão no objeto Structure:
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)

Para ver a sintaxe completa da DSL e exemplos de código CRUD, consulte Criar uma automação no Android.

Sugestões de automação

   Implementado no app de exemplo para Android   

As APIs Home podem sugerir automações para um Structure com base em fatores como os tipos de dispositivo presentes no espaço.

As sugestões de automação são representadas pela classe AutomationSuggestion.

A interface Structure engloba a interface HasSuggestions, que fornece a função suggestions(), que retorna uma coleção de sugestões de automação.

Os métodos likeSuggestion() e dislikeSuggestion() precisam ser conectados aos controles de interface e em que o usuário pode tocar para enviar feedback.

Um terceiro método, clearSuggestionFeedback(), permite que o usuário remova o feedback de uma automação sugerida.

O feedback do usuário influencia as sugestões futuras.

Este exemplo demonstra como recuperar as sugestões de automação disponíveis para um Structure, extrair um ID de sugestão e registrar o feedback do usuário usando likeSuggestion(), clearSuggestionFeedback() e dislikeSuggestion().

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)
    }
  }
}

Parâmetros de comando dinâmicos

Os parâmetros de comando dinâmicos permitem que os desenvolvedores criem parâmetros de ação que são resolvidos dinamicamente no momento da execução, em vez de depender estritamente de valores estáticos e constantes. Isso permite dois recursos principais:

  • Referências que transmitem o valor de uma propriedade de um inicializador (como um payload de evento) ou nó de leitor de estado, ou de variáveis locais declaradas no fluxo de automação.
  • Expressões que capturam valores dinâmicos de tempo de execução (como uma propriedade de evento ou um valor de estado) e transmitem o valor dinâmico diretamente para um parâmetro de comando.

Caso de uso

Vincule um interruptor rotativo físico que envia um evento de pressionamento múltiplo a uma luz regulável. A contagem de cliques é o valor dinâmico transmitido para um comando de etapa LevelControl no ambiente de execução.

Como funcionam os parâmetros dinâmicos

Na DSL de automação no Android, os parâmetros de comando aceitam instâncias Expression ou Reference diretamente no lugar de valores constantes estáticos. A DSL encapsula esses elementos em definições de Parameter ao criar a automação.

Regras de validação

Os parâmetros de comando dinâmicos seguem estas restrições de validação:

  • Presume-se que os parâmetros dinâmicos sejam estruturalmente válidos durante a descoberta, porque as APIs de descoberta só avaliam restrições de valor concretas para argumentos estáticos.
  • Os nós de referência ou expressão precisam aparecer antes no gráfico de automação para que possam ser referenciados em uma ação de comando posterior.

Usar parâmetros de comando dinâmicos no Android

Transmitir expressões dinâmicas diretamente para parâmetros de comando:

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,
        )
      )
    }
  }
}

Como alternativa, atribua uma expressão a uma declaração de variável local e faça referência à variável mais adiante no fluxo:

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,
        )
      )
    }
  }
}

Restrições de tipo

Verifique se os tipos de variáveis e expressões estão alinhados com a definição de tipo de esquema Matter exigida pelo parâmetro do comando de recebimento (como UShort, UByte ou UInt8).

Limites de recurso

Os seguintes limites se aplicam às automações nas APIs Home:

Tabela: limites de recursos da API Automation
Métrica Limite
Número máximo de automações por estrutura 64
Número máximo de nós por automação 128
Número máximo de nós de expressão por automação 64
Número máximo de instâncias de automação por estrutura 1024
Número máximo de instâncias de automação por desenvolvedor por estrutura 64
Número máximo de execuções por estrutura por dia 1024
Número máximo de execuções por desenvolvedor por estrutura por dia 128