Доступ к API устройств можно получить через API Home для Android. Импортируйте эти пакеты в свое приложение:
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
Более подробную информацию см. в разделе Модель данных на Android .
Обработка ошибок
Любой метод в API Home может выдать исключение 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()!!
Подробнее о функции потока Kotlin см. в разделе distinctUntilChanged
Отменить действие в подписке на признак
Интерфейс TraitStateInvalidation
предоставляет возможность сделать недействительным состояние, полученное через подписки на целевое устройство, в случаях, когда состояние не сообщается правильно. Примеры того, когда состояние может быть сообщено неправильно, включают использование атрибутов в признаках Matter с качеством "C" или из-за реализации устройства, которая неожиданно вызывает проблему.
Этот API принудительно считывает текущее состояние признаков и возвращает результат через существующие потоки признаков.
Получите признак, затем запустите forceRead
для признака:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
Получить список характеристик типа устройства
Типы устройств следует использовать в качестве точки входа для считывания характеристик, поскольку они разлагают устройство на его функциональные части (подобно конечным точкам в Matter ).
Они также учитывают столкновения признаков в случае, если устройство имеет два типа устройств, оба из которых могут иметь один и тот же признак. Например, если устройство является одновременно динамиком и регулируемым светом, у него будет два признака включения/выключения и два признака управления уровнем.
Чтобы получить список доступных характеристик для типа устройства Dimmable Light:
// 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. Например, чтобы получить список устройств в доме, которые все имеют черту On/Off:
// Get all devices that support OnOff val onOffDevices: Flow<List<HomeDevice>> = home.devices().map { devices -> devices.filter { it.has(OnOff) } }
Полный список характеристик, доступных в API Home, см. в разделе Интерфейс 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) } }
В API Home есть несколько типов устройств, которые могут представлять основной тип устройства. Например, нет типа устройства "Light". Вместо этого есть четыре разных типа устройств, которые могут представлять свет, как показано в предыдущем примере. Таким образом, чтобы получить полное представление о типе устройства более высокого уровня в доме, в отфильтрованные потоки необходимо включить несколько типов устройств.
Полный список типов устройств, доступных в API Home, см. в интерфейсе 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
.
Метаданные устройств и характеристик
Устройства и характеристики в API Home имеют связанные с ними метаданные, которые могут помочь в управлении пользовательским опытом в приложении.
Каждый признак в API Home содержит свойство sourceConnectivity
, которое содержит информацию о состоянии подключения признака к сети и его местоположении (локальная или удаленная маршрутизация).
Получить основной тип устройства
Некоторые устройства могут представлять несколько типов устройств через API Home. Чтобы убедиться, что пользователям представлены соответствующие параметры в приложении (например, управление устройством и предлагаемые автоматизации) для их устройств, полезно проверить, какой основной тип устройства для устройства.
Сначала получите тип(ы) устройства с помощью type()
, затем определите основной(ые) тип(ы):
val types = device.types().first() val primaryTypes = types.filter { it.metadata.isPrimaryType }
Проверьте, есть ли черта в сети
Используйте метод connectivityState()
для проверки связности признака:
val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState
Некоторые характеристики, как правило, характеристики smart home Google, могут отображаться в автономном режиме, если устройство не имеет подключения к Интернету. Это связано с тем, что эти характеристики основаны на облаке и не имеют локальной маршрутизации.
Проверьте подключение устройства
Подключенность устройства фактически проверяется на уровне типа устройства, поскольку некоторые устройства поддерживают несколько типов устройств. Возвращаемое состояние представляет собой комбинацию состояний подключения для всех признаков на этом устройстве.
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
Состояние PARTIALLY_ONLINE
может наблюдаться в случае смешанных типов устройств, когда нет подключения к Интернету. Стандартные черты Matter могут быть все еще онлайн из-за локальной маршрутизации, но облачные черты будут офлайн.
Проверьте сетевую маршрутизацию признака
Локальность для признака также доступна в API Home. dataSourceLocality
указывает, маршрутизируется ли признак удаленно (через облако), локально (через локальный концентратор) или однорангово (напрямую с устройства на устройство, без концентратора).
Неизвестное значение локальности UNSPECIFIED
возможно, например, когда приложение загружается и еще не достигло концентратора или сервера для подключения устройства. Эти устройства недоступны и не будут отвечать на запросы взаимодействия от команд или событий. Клиент должен определить, как обращаться с такими устройствами.
val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality
Проверьте сетевую маршрутизацию для устройства
Как и подключение, локальность проверяется на уровне типа устройства. Возвращаемое состояние представляет собой комбинацию локальности для всех признаков на этом устройстве.
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
Состояние MIXED
может наблюдаться в аналогичном сценарии, что и PARTIALLY_ONLINE
подключение: некоторые характеристики являются облачными, а другие — локальными.
Изменить имя устройства
Вызовите метод setName()
, чтобы изменить имя устройства:
mixerDevice.setName("Grendel")
список 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() | Получите список всех типов, доступных на устройстве. |