Структурные API на Android

Доступ к API структур можно получить через API Home для Android. Импортируйте эти пакеты в свое приложение:

import com.google.home.Home
import com.google.home.Id
import com.google.home.Structure

Обработка ошибок

Любой метод в API Home может вызвать HomeException , поэтому мы рекомендуем использовать блок try-catch для обработки HomeException при всех вызовах.

При обработке HomeException проверьте поля error.code и error.message , чтобы узнать, что пошло не так. Могут быть и подкоды ошибок, поэтому вызовите метод getSubErrorCodes() и проверьте результат.

Любые необработанные исключения приведут к сбою вашего приложения.

Для получения более подробной информации см. раздел «Обработка ошибок» .

Примеры вызовов

Получить список сооружений

После инициализации вызов функции structures() возвращает поток доступных вам структур:

// Get a flow of all structures accessible to the user
val allStructuresFlow: HomeObjectsFlow<Structure> = home.structures()

// Calling list() on a HomeObjectsFlow returns the first Set of elements.
val allStructures: Set<Structure> = allStructuresFlow.list()

API structures() — это поток, который может не сразу возвращать допустимый список структур. Если ваше приложение реактивное и подписывается на этот поток для управления пользовательским интерфейсом, в конечном итоге должен быть возвращен допустимый список структур. Существуют и другие ситуации, когда может быть возвращен пустой список структур, например, если телефон пользователя теряет связь или если пользователь отозвал разрешения для вашего приложения. Вам следует обязательно обрабатывать эти случаи в своем приложении.

В качестве альтернативы, если вместо реактивного программирования настоятельно требуется императивное программирование, можно использовать терминальный оператор потока:

val everyStructure = withTimeout(5000) { home.structures().first { it.isNotEmpty() } }

Этот вызов ожидает получения корректного списка структур и завершается по истечении заданного приложением времени ожидания.

Получить свойства структуры

Имея на руках список строений, вы можете получить доступ к их свойствам:

// Get a flow on a structure. Flow emits new values on structure metadata changes: name.
val structureFlow: Flow<Structure> = home.structures().itemFlow(myStructureId)

// Get a snapshot of the structure.
val structure: Structure = structureFlow.first()

// Get structure properties
println("id ${structure.id}")
println("name ${structure.name}")

Найти сооружение по названию

Если вам известно имя структуры, вы также можете получить к ней доступ, используя свойство name :

val myHome = home.structures().list().first { it.name == "My home" }

Оттуда становится доступен доступ к объектам недвижимости, помещениям и устройствам каждого здания.

Работа с несколькими структурами

Чтобы использовать несколько структур, получите отдельную ссылку на каждую из них:

var structure1: Structure? = null
var structure2: Structure? = null

try {
  structure1 = home.structures().list().firstOrNull { it.name == "Main House" }
} catch (e: HomeException) {
  // Code for handling the exception
}
try {
  structure2 = home.structures().list().firstOrNull { it.name == "Guest Cottage" }
} catch (e: HomeException) {
  // Code for handling the exception
}

Получить список комнат

Имея на руках структуру здания, вы можете получить список помещений и получить доступ к их характеристикам:

val allRoomsFlow: HomeObjectsFlow<Room> = structure.rooms()
val allRooms: Set<Room> = allRoomsFlow.list()
val room: Room = allRooms.first()

println("id ${room.id}")
println("name ${room.name}")

Создать комнату

Чтобы создать новую комнату:

val testName = "Test Room Name"
val newRoom: Room = structure.createRoom(testName)

Удалить комнату

Или же вы можете удалить комнату:

val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull()
    structure.deleteRoom(roomToDelete!!)

Также можно удалить комнату, указав только ID:

val roomToDelete1 = allRooms.filter { it.id == testRoomId }.firstOrNull()
structure.deleteRoom(roomToDelete1!!)

Если помещение с устройствами будет удалено, устройства останутся в структуре, но больше не будут привязаны к помещению.

Перенесите устройства в другую комнату.

После создания структуры вы можете перемещать устройства в другую комнату внутри этой структуры:

val room2 = structure.rooms().get(Id("room_id_other_structure"))
    val device1 = structure.devices().get(Id("device_id1"))
    structure.moveDevicesToRoom(room2!!, listOf(device1!!))

Если у вас есть только идентификаторы устройства и комнаты, вы также можете перемещать устройства:

structure.moveDevicesToRoom(Id("room_id_other_structure"), listOf(Id("device_id1")))

Изменить название комнаты

Для изменения названия комнаты вызовите метод setName() :

livingRoom.setName("Living Room")

Имена будут усечены, если их длина превышает 60 символов в кодовой точке Unicode, при этом ошибок возникать не будет. Разработчики несут ответственность за обработку длинных имен и, например, могут решить, сообщать ли пользователям о том, что имена будут усечены.

В экосистеме Google Home для большинства типов устройств пользователи могут предоставлять разрешения всем устройствам этого типа одновременно. Для устройств с конфиденциальными или ограниченными правами доступа, таких как замки, камеры или дверные звонки, пользователи должны предоставлять разрешения каждому из них по отдельности.

Чтобы определить, предоставил ли пользователь разрешение на доступ к конфиденциальному или ограниченному типу устройства, используйте функцию consentedDeviceTypes() на уровне структуры:

import com.google.home.Structure
import com.google.home.DeviceType
import com.google.home.DeviceTypeFactory
import com.google.home.consentedDeviceTypes // Extension function from the SDK
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
 * Example of how an app may monitor which device types have been granted access by a user.
 */
fun monitorDeviceConsent(structure: Structure, myScope: CoroutineScope) {
    // Obtain the flow of consented device type factories
    val consentedTypesFlow: Flow<Set<DeviceTypeFactory<out DeviceType>>> =
        structure.consentedDeviceTypes()

    myScope.launch {
        consentedTypesFlow.collect { consentedSet ->
            // Check if the user has consented to share a specific restricted
            // type, such as a Doorbell or Camera.
            val hasCameraAccess = consentedSet.any {
                it.toString() == "matter.google.type.GoogleDoorbellDevice"
            }

            if (hasCameraAccess) {
                // Enable features that require camera access
            } else {
                // Inform the user or disable camera-specific features
            }
        }
    }
}

Автоматизация

Точкой входа в API автоматизации является структура. Чтобы узнать больше об автоматизации в API Home, см. обзор API автоматизации на Android .