Доступ к API устройства можно получить через Home API. Импортируйте эти пакеты в свое приложение:
import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id
Чтобы использовать определенные типы или характеристики устройств с API-интерфейсами устройств, их необходимо импортировать по отдельности.
Например, чтобы использовать свойство Matter On/Off и тип устройства On/Off Plug-in Unit, импортируйте в свое приложение следующие пакеты:
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice
Дополнительные сведения см. в разделе Модель данных .
Обработка ошибок
Любой метод в Home API может вызвать HomeException
, поэтому мы рекомендуем использовать блок try-catch
для перехвата HomeException
при всех вызовах.
При обработке HomeException
проверьте его code
и поля message
, чтобы узнать, что пошло не так.
Любые необработанные исключения приведут к сбою вашего приложения.
Дополнительную информацию см. в разделе Обработка ошибок .
Пример см. в разделе Отправка команды на устройство .
Примеры звонков
Получить список устройств
При наличии структуры вызов devices()
возвращает поток устройств, доступных вам из этой структуры:
// Get a flow of all devices accessible to the user val allDevicesFlow: HomeObjectsFlow<HomeDevice> = home.devices() // Calling list() on a HomeObjectsFlow returns the first Set of elements. val allDevices: Set<HomeDevice> = allDevicesFlow.list()
Отсюда доступны состояния каждого устройства, и на устройство можно отправлять поддерживаемые команды.
Чтение состояния устройства
Давайте рассмотрим пример проверки атрибута OnOff
по признаку On/Off устройства. Используя модель данных признака Home API, где этот признак идентифицируется как OnOff
, вы можете получить данные признака через класс standardTraits
типа устройства:
// Assuming we have a device. val deviceFlow = home.devices().itemFlow(myDeviceId) val device = deviceFlow.first() // Get a flow of a standard trait on the type. distinctUntilChanged() is needed to only trigger // on the specific trait changes and not the whole type. val onOffTraitFlow: Flow<OnOff?> = device.type(DimmableLightDevice).map { it.standardTraits.onOff }.distinctUntilChanged() val onOffTrait: OnOff = onOffTraitFlow.first()!!
См. distinctUntilChanged
чтобы узнать больше о функции потока Kotlin.
Недействительное состояние в подписке типажа
Интерфейс TraitStateInvalidation
предоставляет возможность аннулировать состояние, полученное посредством подписок на целевое устройство, в случаях, когда состояние сообщается неправильно. Примеры случаев, когда состояние может сообщаться неправильно, включают использование атрибутов в характеристиках Matter с качеством «C» или из-за реализации устройства, которая неожиданно вызывает проблему.
Этот API выполняет принудительное чтение текущего состояния типажа и возвращает результат через существующие потоки типажа.
Получите признак, затем запустите forceRead
этого признака:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
Получить список характеристик типа устройства
Типы устройств следует использовать в качестве точки входа для чтения характеристик, поскольку они разлагают устройство на его функциональные части (например, конечные точки в Matter ).
Они также учитывают конфликты характеристик в случае, если устройство имеет два типа устройств, оба из которых могут иметь одну и ту же характеристику. Например, если устройство является одновременно динамиком и регулируемой лампой, оно будет иметь две характеристики «Вкл./Выкл.» и две характеристики «Контроль уровня».
Чтобы получить список доступных характеристик для типа устройства с регулируемой яркостью:
// Get all types available on this device. Requires the types to be part of the registry during // SDK initialization. val typesFlow: Flow<Set<DeviceType>> = device.types() // Get a snapshot of all types. val types: Set<DeviceType> = typesFlow.first() // Get the DimmableLightDevice instance from the set of types. val dimmableLightDevice = types.filterIsInstance<DimmableLightDevice>().firstOrNull() // Get all traits in the type + traits registered val allTraits: Set<Trait> = dimmableLightDevice!!.traits()
Другой вид коллизии признаков может возникнуть, когда устройство имеет два признака с одинаковым именем. Например, onOff
может относиться к экземпляру стандартного признака OnOff
или к экземпляру признака OnOff
, определенного производителем. Чтобы исключить любую потенциальную двусмысленность относительно того, какой признак предназначен, экземпляру Trait
на который ссылается через устройство, должно предшествовать уточняющее пространство имен. Для стандартных черт, то есть тех, которые аналогичны стандартным кластерам Matter , standardTraits
. Для характеристик Google используйте googleTraits
:
// Accessing standard traits on the type. val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl
Чтобы получить доступ к свойству, специфичному для производителя, обратитесь к нему напрямую:
// Accessing a custom trait on the type. val customTrait = dimmableLightDevice.trait(MyCustomTrait)
Получить список устройств с определенной характеристикой
Функцию filter
в Kotlin можно использовать для дальнейшего уточнения вызовов API. Например, чтобы получить список устройств в доме, у которых есть признак «Вкл/Выкл»:
// Get all devices that support OnOff val onOffDevices: Flow<List<HomeDevice>> = home.devices().map { devices -> devices.filter { it.has(OnOff) } }
Полный список свойств, доступных в Home API, см. в интерфейсе Trait
.
Получить список устройств с похожими типами устройств
Чтобы получить список устройств, представляющих все источники света в доме:
// Get a list of devices with similar device types (lights) val lightDevices = home.devices().map { devices -> devices.filter { it.has(DimmableLightDevice) || it.has(OnOffLightDevice) || it.has(ColorTemperatureLightDevice) || it.has(ExtendedColorLightDevice) } }
В Home API есть несколько типов устройств, которые могут представлять основной тип устройства. Например, нет типа устройства «Легкий». Вместо этого существует четыре разных типа устройств, которые могут представлять свет, как показано в предыдущем примере. Таким образом, чтобы получить комплексное представление о типах устройств более высокого уровня в доме, в отфильтрованные потоки необходимо включить несколько типов устройств.
Полный список типов устройств, доступных в Home API, см. в интерфейсе DeviceType
Получите идентификатор поставщика или идентификатор продукта для устройства.
Признак BasicInformation
включает в себя такую информацию, как идентификатор поставщика, идентификатор продукта, название продукта и серийный номер устройства:
// Get device basic information. All general information traits are on the RootNodeDevice type. val basicInformation = device.type(RootNodeDevice).first().standardTraits.basicInformation!! println("vendorName ${basicInformation.vendorName}") println("vendorId ${basicInformation.vendorId}") println("productId ${basicInformation.productId}")
Определите устройства, использующие соединение «облако-облако»
Если вы являетесь производителем устройств и создаете устройства Cloud-to-cloud , чтобы идентифицировать ваши устройства Cloud-to-cloud с помощью признака BasicInformation
, вы можете включить эти строковые поля в их ответ SYNC
:
Альянс стандартов связи (CSA) выдал идентификатор поставщика:
"matterOriginalVendorId": "0xfff1",
Идентификатор продукта, который однозначно идентифицирует продукт поставщика:
"matterOriginalProductId": "0x1234",
Уникальный идентификатор устройства, созданный в соответствии с требованиями производителя:
"matterUniqueId": "matter-device-id",
При вводе этих строковых полей используйте идентификаторы поставщика Matter и идентификаторы продукта, если они у вас есть. Если вы не являетесь членом CSA и вам не были назначены эти идентификаторы, вы можете оставить поля matterOriginalVendorId
и matterOriginalProductId
пустыми и указать matterUniqueId
в качестве идентификатора.
В примере ответа SYNC показано использование этих полей:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"agentUserId": "1836.15267389",
"devices": [
{
"id": "456",
"type": "action.devices.types.LIGHT",
"traits": [
"action.devices.traits.OnOff",
"action.devices.traits.Brightness",
"action.devices.traits.ColorSetting",
],
"willReportState": true,
"deviceInfo": { ... },
"matterOriginalVendorId": "0xfff1",
"matterOriginalProductId": "0x1234",
"matterUniqueId": "matter-device-id",
"otherDeviceIds": [
{
"deviceId": "local-device-id",
}
]
}
]
}
}
Дополнительную информацию см. в документации Cloud-to-cloud SYNC
.
Метаданные устройства и характеристик
Устройства и характеристики в Home API имеют связанные с ними метаданные, которые могут помочь в управлении взаимодействием с пользователем в приложении.
Каждый признак в Home API содержит свойство sourceConnectivity
, которое содержит информацию об онлайн-статусе и местонахождении признака (локальная или удаленная маршрутизация).
Получить основной тип устройства
Некоторые устройства могут представлять несколько типов устройств через Home API. Чтобы гарантировать, что пользователям предоставляются соответствующие параметры в приложении (например, управление устройствами и предлагаемые средства автоматизации) для их устройств, полезно проверить, какой тип устройства является основным.
Сначала получите тип(ы) устройства с помощью type()
, затем определите, какой тип является основным:
val types = device.types().first() val primaryType = types.first { it.metadata.isPrimaryType }
Проверьте, находится ли черта в сети
Используйте метод connectivityState()
чтобы проверить связность признака:
val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState
Некоторые функции, обычно функции smart home Google, могут отображаться в автономном режиме, если устройство не имеет подключения к Интернету. Это связано с тем, что эти функции основаны на облаке и не имеют локальной маршрутизации.
Проверка подключения устройства
Возможность подключения устройства фактически проверяется на уровне типа устройства, поскольку некоторые устройства поддерживают несколько типов устройств. Возвращаемое состояние представляет собой комбинацию состояний подключения для всех характеристик на этом устройстве.
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
Состояние PARTIALLY_ONLINE
может наблюдаться в случае устройств смешанного типа, когда нет подключения к Интернету. Стандартные свойства Matter могут по-прежнему находиться в сети из-за локальной маршрутизации, но облачные свойства будут отключены.
Проверьте сетевую маршрутизацию признака
Местоположение признака также доступно в Home API. dataSourceLocality
указывает, маршрутизируется ли признак удаленно (через облако), локально (через локальный концентратор) или в одноранговой сети (напрямую от устройства к устройству, без концентратора).
Неизвестное значение местоположения UNSPECIFIED
возможно, например, когда приложение загружается и еще не достигло концентратора или сервера для подключения устройства. Эти устройства недоступны и не будут выполнять запросы на взаимодействие от команд или событий. Клиент сам решает, как обращаться с такими устройствами.
val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality
Проверьте сетевую маршрутизацию устройства
Как и возможность подключения, локальность проверяется на уровне типа устройства. Возвращаемое состояние представляет собой комбинацию местоположения для всех признаков на этом устройстве.
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
Состояние MIXED
можно наблюдать в сценарии, аналогичном сценарию подключения PARTIALLY_ONLINE
: некоторые характеристики основаны на облаке, а другие — локальны.
Список API
После создания экземпляра Home
через него становятся доступны следующие API-интерфейсы устройств:
API | Описание |
---|---|
devices() | Получите все устройства во всех структурах аккаунта Google. Возвращает HomeObjectsFlow , предоставляющий дополнительные параметры поиска и фильтрации. |
Если у вас есть HomeDevice
, через него будут доступны следующие API:
API | Описание |
---|---|
allCandidates() | Возвращает всех кандидатов на автоматизацию для устройства и его дочерних элементов. |
candidates() | Возвращает всех кандидатов на автоматизацию для устройства. |
connectivityStateChanged | Последний раз состояние устройства менялось. |
events(event) | Получает поток определенного события. |
events(trait) | Получает поток всех событий по этому признаку. |
events(traits) | Получает поток всех событий по этим признакам. |
getSourceConnectivity(trait) | Получите метаданные для определенного признака. Возвращает SourceConnectivity . |
has(trait) | Проверьте, поддерживается ли текущая запрошенная характеристика устройством. |
has(type) | Если устройство поддерживает указанный тип. |
id | Уникальный системный идентификатор устройства. |
isInRoom | Если устройство находится в комнате. |
isInStructure | Если устройство находится в конструкции. |
isMatterDevice | Если устройство поддерживается Matter . |
name | Имя устройства, предоставленное пользователем. |
room() | Комната, которой назначено устройство. Возвращает Room . |
roomId | Идентификатор комнаты, которой присвоено устройство. Возвращает Id . |
sourceConnectivity | Исходное подключение устройства, представляющее совокупные состояния подключения и сетевую локальность характеристик устройства. |
structure() | Структура, которой присвоено устройство. Возвращает Structure . |
structureId | Идентификатор структуры, которой присвоено устройство. Возвращает Id . |
type(type) | Получите определение типа с заполненными признаками (если они доступны) для прямого доступа. Всегда возвращает актуальный снимок признаков. |
types() | Получите список всех типов, доступных на устройстве. |